Skip to content

Commit

Permalink
make external event dragging work with constraint/overlap system
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Nov 13, 2014
1 parent 9241d7c commit 7acef25
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 39 deletions.
84 changes: 51 additions & 33 deletions src/EventManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,11 +597,12 @@ function EventManager(options) { // assumed to be a calendar

// If the given event is a recurring event, break it down into an array of individual instances.
// If not a recurring event, return an array with the single original event.
// If given a falsy input (probably because of a failed buildEventFromInput call), returns an empty array.
function expandEvent(abstractEvent) {
var events = [];
var view;
var _rangeStart = rangeStart;
var _rangeEnd = rangeEnd;
var view;
var dowHash;
var dow;
var i;
Expand All @@ -617,48 +618,50 @@ function EventManager(options) { // assumed to be a calendar
_rangeEnd = view.end;
}

if (abstractEvent._recurring) {
if (abstractEvent) {
if (abstractEvent._recurring) {

// make a boolean hash as to whether the event occurs on each day-of-week
if ((dow = abstractEvent.dow)) {
dowHash = {};
for (i = 0; i < dow.length; i++) {
dowHash[dow[i]] = true;
// make a boolean hash as to whether the event occurs on each day-of-week
if ((dow = abstractEvent.dow)) {
dowHash = {};
for (i = 0; i < dow.length; i++) {
dowHash[dow[i]] = true;
}
}
}

// iterate through every day in the current range
date = _rangeStart.clone().stripTime(); // holds the date of the current day
while (date.isBefore(_rangeEnd)) {
// iterate through every day in the current range
date = _rangeStart.clone().stripTime(); // holds the date of the current day
while (date.isBefore(_rangeEnd)) {

if (!dowHash || dowHash[date.day()]) { // if everyday, or this particular day-of-week
if (!dowHash || dowHash[date.day()]) { // if everyday, or this particular day-of-week

startTime = abstractEvent.start; // the stored start and end properties are times (Durations)
endTime = abstractEvent.end; // "
start = date.clone();
end = null;
startTime = abstractEvent.start; // the stored start and end properties are times (Durations)
endTime = abstractEvent.end; // "
start = date.clone();
end = null;

if (startTime) {
start = start.timeDuration(startTime);
}
if (endTime) {
end = date.clone().timeDuration(endTime);
if (startTime) {
start = start.timeDuration(startTime);
}
if (endTime) {
end = date.clone().timeDuration(endTime);
}

event = $.extend({}, abstractEvent); // make a copy of the original
assignDatesToEvent(
start, end,
!startTime && !endTime, // allDay?
event
);
events.push(event);
}

event = $.extend({}, abstractEvent); // make a copy of the original
assignDatesToEvent(
start, end,
!startTime && !endTime, // allDay?
event
);
events.push(event);
date.add(1, 'days');
}

date.add(1, 'days');
}
}
else {
events.push(abstractEvent); // return the original event. will be a one-item array
else {
events.push(abstractEvent); // return the original event. will be a one-item array
}
}

return events;
Expand Down Expand Up @@ -882,6 +885,7 @@ function EventManager(options) { // assumed to be a calendar

t.isEventAllowedInRange = isEventAllowedInRange;
t.isSelectionAllowedInRange = isSelectionAllowedInRange;
t.isExternalDragAllowedInRange = isExternalDragAllowedInRange;


function isEventAllowedInRange(event, start, end) {
Expand Down Expand Up @@ -911,6 +915,20 @@ function EventManager(options) { // assumed to be a calendar
}


function isExternalDragAllowedInRange(start, end, eventInput) { // eventInput is optional associated event data
var event;

if (eventInput) {
event = expandEvent(buildEventFromInput(eventInput))[0];
if (event) {
return isEventAllowedInRange(event, start, end);
}
}

return isRangeAllowed(start, end);
}


// Returns true if the given range (caused by an event drop/resize or a selection) is allowed to exist
// according to the constraint/overlap settings.
// `event` is not required if checking a selection.
Expand Down
26 changes: 20 additions & 6 deletions src/common/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,13 @@ View.prototype = {
documentDragStart: function(ev, ui) {
var _this = this;
var calendar = this.calendar;
var eventStart = null;
var eventStart = null; // a null value signals an unsuccessful drag
var eventEnd = null;
var visibleEnd = null; // will be calculated event when no eventEnd
var el;
var accept;
var meta;
var eventProps; // if an object, signals an event should be created upon drop
var dragListener;

if (this.opt('droppable')) { // only listen if this setting is on
Expand All @@ -275,27 +276,41 @@ View.prototype = {
if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {

meta = getDraggedElMeta(el); // data for possibly creating an event
eventProps = meta.eventProps;

// listener that tracks mouse movement over date-associated pixel regions
dragListener = new DragListener(this.coordMap, {
cellOver: function(cell, cellDate) {
eventStart = cellDate;
eventEnd = meta.duration ? eventStart.clone().add(meta.duration) : null;
visibleEnd = eventEnd || calendar.getDefaultEventEnd(!eventStart.hasTime(), eventStart);
_this.renderDrag(eventStart, visibleEnd);

// keep the start/end up to date when dragging
if (eventProps) {
$.extend(eventProps, { start: eventStart, end: eventEnd });
}

if (calendar.isExternalDragAllowedInRange(eventStart, visibleEnd, eventProps)) {
_this.renderDrag(eventStart, visibleEnd);
}
else {
eventStart = null; // signal unsuccessful
disableCursor();
}
},
cellOut: function() {
eventStart = eventEnd = visibleEnd = null;
eventStart = null;
_this.destroyDrag();
enableCursor();
}
});

// gets called, only once, when jqui drag is finished
$(document).one('dragstop', function(ev, ui) {
var eventProps = meta.eventProps;
var renderedEvents;

_this.destroyDrag();
enableCursor();

if (eventStart) { // element was dropped on a valid date/time cell

Expand All @@ -307,9 +322,8 @@ View.prototype = {
// trigger 'drop' regardless of whether element represents an event
_this.trigger('drop', el[0], eventStart, ev, ui);

// create an event from the given properties and the newly calculated dates
// create an event from the given properties and the latest dates
if (eventProps) {
$.extend(eventProps, { start: eventStart, end: eventEnd });
renderedEvents = calendar.renderEvent(eventProps, meta.stick);
_this.trigger('eventReceive', null, renderedEvents[0]); // signal an external event landed
}
Expand Down

0 comments on commit 7acef25

Please sign in to comment.