From: Jan Schneider Date: Wed, 28 Oct 2009 13:17:54 +0000 (+0100) Subject: Only add resize handlers to the first and last day of multi-day events. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=af9ac22e40d87bffa3008939c6fe0d7443a6e4fc;p=horde.git Only add resize handlers to the first and last day of multi-day events. Implement dragging (not resizing yet) of multi-day events. --- diff --git a/kronolith/ajax.php b/kronolith/ajax.php index 4b9c338fb..67c2605ec 100644 --- a/kronolith/ajax.php +++ b/kronolith/ajax.php @@ -258,6 +258,16 @@ try { $event->end->hour = $event->end->min = $event->end->sec = 0; } break; + + case 'offDays': + $event->start->mday += $value; + $event->end->mday += $value; + break; + + case 'offMins': + $event->start->min += $value; + $event->end->min += $value; + break; } } $result = saveEvent($event); diff --git a/kronolith/js/kronolith.js b/kronolith/js/kronolith.js index aa2e3f3e9..a39fbe176 100644 --- a/kronolith/js/kronolith.js +++ b/kronolith/js/kronolith.js @@ -1044,17 +1044,30 @@ KronolithCore = { var midnight = this.parseDate(date), innerDiv = new Element('DIV', { 'class': 'kronolithEventInfo' }), - draggerTop = new Element('DIV', { 'id': event.value.nodeId + 'top', 'class': 'kronolithDragger kronolithDraggerTop' }).setStyle(style), + draggerTop, draggerBottom; + if (event.value.fi) { + draggerTop = new Element('DIV', { 'id': event.value.nodeId + 'top', 'class': 'kronolithDragger kronolithDraggerTop' }).setStyle(style); + } else { + innerDiv.setStyle({ 'top': 0 }); + } + if (event.value.la) { draggerBottom = new Element('DIV', { 'id': event.value.nodeId + 'bottom', 'class': 'kronolithDragger kronolithDraggerBottom' }).setStyle(style); + } else { + innerDiv.setStyle({ 'bottom': 0 }); + } div.setStyle({ 'top': (Math.round(midnight.getElapsed(event.value.start) / 60000) * this[storage].height / 60 + this[storage].offset | 0) + 'px', 'height': (Math.round(event.value.start.getElapsed(event.value.end) / 60000) * this[storage].height / 60 - this[storage].spacing | 0) + 'px', 'width': '100%' }) - .insert(innerDiv.setStyle(style)) - .insert(draggerTop) - .insert(draggerBottom); + .insert(innerDiv.setStyle(style)); + if (draggerTop) { + div.insert(draggerTop); + } + if (draggerBottom) { + div.insert(draggerBottom); + } $(view == 'day' ? 'kronolithEventsDay' : 'kronolithEventsWeek' + date).insert(div); if (event.value.pe) { @@ -1062,29 +1075,43 @@ KronolithCore = { // Top-most position (minimum y) of top dragger var minTop = this[storage].allDay + this[storage].spacing, // Number of pixels that cover 10 minutes. - step = this[storage].height / 6, + step = this[storage].height / 6; + if (draggerTop) { // Top position of top dragger - dragTop = draggerTop.cumulativeOffset().top, + var dragTop = draggerTop.cumulativeOffset().top; + } + if (draggerBottom) { // Top position of bottom dragger - dragBottom = draggerBottom.cumulativeOffset().top, - // Height of bottom dragger - dragBottomHeight = draggerBottom.getHeight(), + var dragBottom = draggerBottom.cumulativeOffset().top, + // Height of bottom dragger + dragBottomHeight = draggerBottom.getHeight(); + } // Top position of the whole event div - eventTop = div.cumulativeOffset().top, + var eventTop = div.cumulativeOffset().top; + if (draggerTop) { // Bottom-most position (maximum y) of top dragger - maxTop = div.offsetTop + draggerBottom.offsetTop + var maxTop = div.offsetTop - minTop - draggerTop.getHeight() - - parseInt(innerDiv.getStyle('lineHeight')), + - parseInt(innerDiv.getStyle('lineHeight')); + if (draggerBottom) { + maxTop += draggerBottom.offsetTop; + } + } + if (draggerBottom) { // Top-most position (minimum y) of bottom dragger (upper // edge) - minBottom = div.offsetTop - minTop + draggerTop.getHeight() + var minBottom = div.offsetTop - minTop + parseInt(innerDiv.getStyle('lineHeight')), // Bottom-most position (maximum y) of bottom dragger // (upper edge) maxBottom = 24 * this[storage].height - + this[storage].allDay - dragBottomHeight, + + this[storage].allDay - dragBottomHeight; + if (draggerTop) { + minBottom += draggerTop.getHeight(); + } + } // Height of the whole event div - divHeight = div.getHeight(), + var divHeight = div.getHeight(), // Maximum height of the whole event div maxDiv = 24 * this[storage].height + this[storage].allDay @@ -1101,7 +1128,7 @@ KronolithCore = { this.addClassName('kronolithSelected'); }.bind(div), 'onEnd': function(d, e) { - this[0]._onDragEnd(d, this[1], innerDiv, event, midnight, view); + this[0]._onDragEnd(d, this[1], innerDiv, event, midnight, view, step); }.bind([this, div]), 'onDrag': function(d, e) { var div = this[1], @@ -1130,17 +1157,21 @@ KronolithCore = { }.bind([this, div]) }; - opts.snap = function(x, y, elm) { - y = Math.max(0, step * (Math.min(maxTop, y - minTop) / step | 0)) + minTop; - return [0, y]; + if (draggerTop) { + opts.snap = function(x, y, elm) { + y = Math.max(0, step * (Math.min(maxTop, y - minTop) / step | 0)) + minTop; + return [0, y]; + } + new Drag(event.value.nodeId + 'top', opts); } - new Drag(event.value.nodeId + 'top', opts); - opts.snap = function(x, y, elm) { - y = Math.min(maxBottom - minTop + dragBottomHeight + KronolithCore[storage].spacing, step * ((Math.max(minBottom, y - minTop) + dragBottomHeight + KronolithCore[storage].spacing) / step | 0)) + minTop - dragBottomHeight - KronolithCore[storage].spacing; - return [0, y]; + if (draggerBottom) { + opts.snap = function(x, y, elm) { + y = Math.min(maxBottom - minTop + dragBottomHeight + KronolithCore[storage].spacing, step * ((Math.max(minBottom, y - minTop) + dragBottomHeight + KronolithCore[storage].spacing) / step | 0)) + minTop - dragBottomHeight - KronolithCore[storage].spacing; + return [0, y]; + } + new Drag(event.value.nodeId + 'bottom', opts); } - new Drag(event.value.nodeId + 'bottom', opts); if (view == 'week') { var dates = this.viewDates(midnight, view), @@ -1150,6 +1181,7 @@ KronolithCore = { maxLeft = $('kronolithEventsWeek' + dates[1].toString('yyyyMMdd')).offsetLeft - $('kronolithEventsWeek' + date).offsetLeft, stepX = (maxLeft - minLeft) / 6; } + var startTop = div.offsetTop - minTop; new Drag(div, { 'threshold': 5, 'nodrop': true, @@ -1173,15 +1205,18 @@ KronolithCore = { } if (view == 'week') { var offsetX = Math.round(d.ghost.offsetLeft / stepX); + event.value.offsetDays = offsetX; this[0]._calculateEventDates(event.value, storage, step, d.ghost.offsetTop - minTop, divHeight, eventStart.clone().addDays(offsetX), eventEnd.clone().addDays(offsetX)); } else { + event.value.offsetDays = 0; this[0]._calculateEventDates(event.value, storage, step, d.ghost.offsetTop - minTop, divHeight); } + event.value.offsetTop = d.ghost.offsetTop - minTop - startTop; d.innerDiv.update('(' + event.value.start.toString(Kronolith.conf.time_format) + ' - ' + event.value.end.toString(Kronolith.conf.time_format) + ') ' + event.value.t.escapeHTML()); this[1].clonePosition(d.ghost); }.bind([this, div]), 'onEnd': function(d, e) { - this[0]._onDragEnd(d, this[1], innerDiv, event, midnight, view); + this[0]._onDragEnd(d, this[1], innerDiv, event, midnight, view, step); }.bind([this, div]), }); } @@ -1325,15 +1360,23 @@ KronolithCore = { /** * Called as the event handler after dragging/resizing a day/week event. */ - _onDragEnd: function(drag, div, innerDiv, event, date, view) + _onDragEnd: function(drag, div, innerDiv, event, date, view, step) { var dates = this.viewDates(date, view), start = dates[0].toString('yyyyMMdd'), - end = dates[1].toString('yyyyMMdd'); + end = dates[1].toString('yyyyMMdd'), + attributes; div.removeClassName('kronolithSelected'); this._setEventText(innerDiv, event.value); drag.destroy(); this.startLoading(event.value.calendar, start, end); + if (Object.isUndefined(event.value.offsetTop)) { + attributes = $H({ 'start': event.value.start, + 'end': event.value.end }); + } else { + attributes = $H({ 'offDays': event.value.offsetDays, + 'offMins': event.value.offsetTop / step * 10 }); + } this.doAction( 'UpdateEvent', { 'cal': event.value.calendar, @@ -1341,10 +1384,7 @@ KronolithCore = { 'view': view, 'view_start': start, 'view_end': end, - 'att': $H({ - start: event.value.start, - end: event.value.end, - }).toJSON() + 'att': attributes.toJSON() }, function(r) { if (r.response.events) { diff --git a/kronolith/lib/Event.php b/kronolith/lib/Event.php index a0b55e99f..88ff1c90b 100644 --- a/kronolith/lib/Event.php +++ b/kronolith/lib/Event.php @@ -108,11 +108,25 @@ abstract class Kronolith_Event /** * This tag's events. * - * @var mixed Array of tags or comma delimited string. + * @var array|string */ public $tags = array(); /** + * Whether this is the event on the first day of a multi-day event. + * + * @var boolen + */ + public $first = true; + + /** + * Whether this is the event on the last day of a multi-day event. + * + * @var boolen + */ + public $last = true; + + /** * All the attendees of this event. * * This is an associative array where the keys are the email addresses @@ -1073,6 +1087,8 @@ abstract class Kronolith_Event * - c: calendar id * - s: start date * - e: end date + * - fi: first day of a multi-day event + * - la: last day of a multi-day event * - x: status (Kronolith::STATUS_* constant) * - al: all-day? * - bg: background color @@ -1107,6 +1123,8 @@ abstract class Kronolith_Event $json->c = $this->getCalendar(); $json->s = $this->start->toJson(); $json->e = $this->end->toJson(); + $json->fi = $this->first; + $json->la = $this->last; $json->x = $this->status; $json->al = is_null($allDay) ? $this->isAllDay() : $allDay; $json->bg = $this->_backgroundColor; diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index 1ee54ed15..6f69873ab 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -511,10 +511,10 @@ class Kronolith $eventEnd = $endDate; } } else { - /* If the event doesn't end at 12am set the end date to the - * current end date. If it ends at 12am and does not end at - * the same time that it starts (0 duration), set the end date - * to the previous day's end date. */ + /* If the event doesn't end at 12am set the end date to + * the current end date. If it ends at 12am and does not + * end at the same time that it starts (0 duration), set + * the end date to the previous day's end date. */ if ($event->end->hour != 0 || $event->end->min != 0 || $event->end->sec != 0 || @@ -555,6 +555,7 @@ class Kronolith $addEvent->start = new Horde_Date(array( 'hour' => 0, 'min' => 0, 'sec' => 0, 'month' => $loopDate->month, 'mday' => $loopDate->mday, 'year' => $loopDate->year)); + $addEvent->first = false; } /* If this is the end day, set the end time to the @@ -565,6 +566,7 @@ class Kronolith $addEvent->end = new Horde_Date(array( 'hour' => 23, 'min' => 59, 'sec' => 59, 'month' => $loopDate->month, 'mday' => $loopDate->mday, 'year' => $loopDate->year)); + $addEvent->last = false; } $results[$loopDate->dateString()][$addEvent->getId()] = $json ? $addEvent->toJson($allDay) : $addEvent; @@ -596,12 +598,19 @@ class Kronolith { $loopDate = new Horde_Date($eventStart->year, $eventStart->month, $eventStart->mday); $allDay = $event->isAllDay(); + $first = true; while ($loopDate->compareDateTime($eventEnd) <= 0) { if (!$allDay || $loopDate->compareDateTime($eventEnd) != 0) { $addEvent = clone $event; $addEvent->start = $eventStart; $addEvent->end = $eventEnd; + if ($loopDate->compareDate($eventStart) != 0) { + $addEvent->first = false; + } + if ($loopDate->compareDate($eventEnd) != 0) { + $addEvent->last = false; + } $results[$loopDate->dateString()][$addEvent->getId()] = $json ? $addEvent->toJson($allDay) : $addEvent; } $loopDate->mday++;