From 874e5174bb66546ccc7ea7ddd8affdfbe6c6bf1f Mon Sep 17 00:00:00 2001 From: Sean Kenny Date: Sat, 18 Oct 2014 09:47:37 +0100 Subject: [PATCH] Update to allow click events --- src/resource/ResourceDayGrid.js | 51 +++++++++++++++++- src/resource/ResourceTimeGrid.js | 91 ++++++++++++++++++++++++++++++++ tests/resourceDayView.html | 14 ++--- 3 files changed, 148 insertions(+), 8 deletions(-) diff --git a/src/resource/ResourceDayGrid.js b/src/resource/ResourceDayGrid.js index 0449963..aae6eb3 100644 --- a/src/resource/ResourceDayGrid.js +++ b/src/resource/ResourceDayGrid.js @@ -9,9 +9,58 @@ function ResourceDayGrid(view) { ResourceDayGrid.prototype = createObject(DayGrid.prototype); // declare the super-class $.extend(ResourceDayGrid.prototype, { + // Renders a visual indication of an event hovering over the given date(s). + // `end` can be null, as well as `seg`. See View's documentation on renderDrag for more info. + // A returned value of `true` signals that a mock "helper" event has been rendered. + renderDrag: function(start, end, seg) { + var opacity; + + // always render a highlight underneath + this.renderHighlight( + start, + end || this.view.calendar.getDefaultEventEnd(true, start), + seg.event.resources + ); + + // if a segment from the same calendar but another component is being dragged, render a helper event + if (seg && !seg.el.closest(this.el).length) { + + this.renderRangeHelper(start, end, seg); + + opacity = this.view.opt('dragOpacity'); + if (opacity !== undefined) { + this.helperEls.css('opacity', opacity); + } + + return true; // a helper has been rendered + } + }, + + // Renders an emphasis on the given date range. `start` is an inclusive, `end` is exclusive. + renderHighlight: function(start, end, resourceIds) { + var segs = this.rangeToSegs(start, end, resourceIds); + var highlightNodes = []; + var i, seg; + var el; + + // build an event skeleton for each row that needs it + for (i = 0; i < segs.length; i++) { + seg = segs[i]; + el = $( + this.highlightSkeletonHtml(seg.leftCol, seg.rightCol + 1) // make end exclusive + ); + el.appendTo(this.rowEls[seg.row]); + highlightNodes.push(el[0]); + } + + this.highlightEls = $(highlightNodes); // array -> jQuery set + }, + + rangeToSegs: function(rangeStart, rangeEnd, resourceIds) { var col, segments = []; - + resourceIds = resourceIds || []; + var currentDate = this.view.calendar.getDate(); if((rangeStart <= currentDate) && (currentDate < rangeEnd)) { var view = this.view; diff --git a/src/resource/ResourceTimeGrid.js b/src/resource/ResourceTimeGrid.js index a0bcc33..bc705a2 100644 --- a/src/resource/ResourceTimeGrid.js +++ b/src/resource/ResourceTimeGrid.js @@ -41,6 +41,97 @@ $.extend(ResourceTimeGrid.prototype, { } return segs; + }, + // Process a mousedown on an element that represents a day. For day clicking and selecting. + dayMousedown: function(ev) { + var _this = this; + var view = this.view; + var isSelectable = view.opt('selectable'); + var dates = null; // the inclusive dates of the selection. will be null if no selection + var start; // the inclusive start of the selection + var end; // the *exclusive* end of the selection + var dayEl; + + // this listener tracks a mousedown on a day element, and a subsequent drag. + // if the drag ends on the same day, it is a 'dayClick'. + // if 'selectable' is enabled, this listener also detects selections. + var dragListener = new DragListener(this.coordMap, { + //distance: 5, // needs more work if we want dayClick to fire correctly + scroll: view.opt('dragScroll'), + dragStart: function() { + view.unselect(); // since we could be rendering a new selection, we want to clear any old one + }, + cellOver: function(cell, date) { + if (dragListener.origDate) { // click needs to have started on a cell + + dayEl = _this.getCellDayEl(cell); + + dates = [ date, dragListener.origDate ].sort(dateCompare); + start = dates[0]; + end = dates[1].clone().add(_this.cellDuration); + + if (isSelectable) { + var resources = view.calendar.fetchResources(); + _this.renderSelection(start, end, {event: { resources: [ resources[cell.col].id ]}}); + } + } + }, + cellOut: function(cell, date) { + dates = null; + _this.destroySelection(); + }, + listenStop: function(ev) { + if (dates) { // started and ended on a cell? + if (dates[0].isSame(dates[1])) { + view.trigger('dayClick', dayEl[0], start, ev); + } + if (isSelectable) { + // the selection will already have been rendered. just report it + view.reportSelection(start, end, ev); + } + } + } + }); + + dragListener.mousedown(ev); // start listening, which will eventually initiate a dragStart + }, + + // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. + renderSelection: function(start, end, sourceSeg) { + if (this.view.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered + this.renderRangeHelper(start, end, sourceSeg); + } + else { + this.renderHighlight(start, end, sourceSeg); + } + }, + // Renders a mock event over the given date(s). + // `end` can be null, in which case the mock event that is rendered will have a null end time. + // `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging. + renderRangeHelper: function(start, end, sourceSeg) { + var view = this.view; + var fakeEvent; + + // compute the end time if forced to do so (this is what EventManager does) + if (!end && view.opt('forceEventDuration')) { + end = view.calendar.getDefaultEventEnd(!start.hasTime(), start); + } + + fakeEvent = sourceSeg ? createObject(sourceSeg.event) : {}; // mask the original event object if possible + fakeEvent.start = start; + fakeEvent.end = end; + fakeEvent.allDay = !(start.hasTime() || (end && end.hasTime())); // freshly compute allDay + + // this extra className will be useful for differentiating real events from mock events in CSS + fakeEvent.className = (fakeEvent.className || []).concat('fc-helper'); + + // if something external is being dragged in, don't render a resizer + if (!sourceSeg) { + fakeEvent.editable = false; + fakeEvent.resources = sourceSeg.event.resources; + } + + this.renderHelper(fakeEvent, sourceSeg); // do the actual rendering } }); diff --git a/tests/resourceDayView.html b/tests/resourceDayView.html index a7af103..d2d0eda 100644 --- a/tests/resourceDayView.html +++ b/tests/resourceDayView.html @@ -72,7 +72,7 @@ { 'id': 'resource3', 'name': 'Resource 3' }], events: [ { - title: 'R1: All day', + title: 'R1/R3: All day', allDay: true, start: new Date(y, m, d, 12, 0), resources: ['resource1', 'resource3'] @@ -106,14 +106,14 @@ } ], eventDrop: function(event, delta, revertFunc) { - if (!confirm("Are you sure about this change?")) { - revertFunc(); - } + // if (!confirm("Are you sure about this change?")) { + // revertFunc(); + // } }, eventResize: function (event, delta, revertFunc) { - if (!confirm("Are you sure about this change?")) { - revertFunc(); - } + // if (!confirm("Are you sure about this change?")) { + // revertFunc(); + // } } }); });