|
|
@@ -10,32 +10,17 @@ Contains:
|
|
|
- initializing event rendering-related options
|
|
|
*/
|
|
|
|
|
|
-var Grid = FC.Grid = ChronoComponent.extend(SegChronoComponentMixin, {
|
|
|
-
|
|
|
- // self-config, overridable by subclasses
|
|
|
- hasDayInteractions: true, // can user click/select ranges of time?
|
|
|
+var Grid = FC.Grid = CoordChronoComponent.extend(SegChronoComponentMixin, {
|
|
|
|
|
|
view: null, // a View object
|
|
|
- isRTL: null, // shortcut to the view's isRTL option
|
|
|
-
|
|
|
- hitsNeededDepth: 0, // necessary because multiple callers might need the same hits
|
|
|
-
|
|
|
- dayClickListener: null,
|
|
|
- daySelectListener: null,
|
|
|
- segDragListener: null,
|
|
|
- segResizeListener: null,
|
|
|
- externalDragListener: null,
|
|
|
|
|
|
|
|
|
constructor: function(view) {
|
|
|
this.view = view; // do this first, for opt()
|
|
|
|
|
|
- ChronoComponent.call(this);
|
|
|
+ CoordChronoComponent.apply(this, arguments);
|
|
|
|
|
|
this.initFillSystem(); // TODO: SegChronoComponentMixin should be responsible
|
|
|
-
|
|
|
- this.dayClickListener = this.buildDayClickListener();
|
|
|
- this.daySelectListener = this.buildDaySelectListener();
|
|
|
},
|
|
|
|
|
|
|
|
|
@@ -69,224 +54,9 @@ var Grid = FC.Grid = ChronoComponent.extend(SegChronoComponentMixin, {
|
|
|
|
|
|
|
|
|
unrenderEvents: function() {
|
|
|
- this.clearDragListeners(); // we wanted to add this action to event rendering teardown
|
|
|
- SegChronoComponentMixin.unrenderEvents.apply(this, arguments);
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /* Hit Area
|
|
|
- ------------------------------------------------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-
|
|
|
- hitsNeeded: function() {
|
|
|
- if (!(this.hitsNeededDepth++)) {
|
|
|
- this.prepareHits();
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- hitsNotNeeded: function() {
|
|
|
- if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) {
|
|
|
- this.releaseHits();
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- getSafeHitFootprint: function(hit) {
|
|
|
- var footprint = this.getHitFootprint(hit);
|
|
|
-
|
|
|
- if (!this.view.activeUnzonedRange.containsRange(footprint.unzonedRange)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- return footprint;
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- getHitFootprint: function(hit) {
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- // Given position-level information about a date-related area within the grid,
|
|
|
- // should return a jQuery element that best represents it. passed to dayClick callback.
|
|
|
- getHitEl: function(hit) {
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /* Rendering
|
|
|
- ------------------------------------------------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-
|
|
|
- // Sets the container element that the grid should render inside of.
|
|
|
- // Does other DOM-related initializations.
|
|
|
- setElement: function(el) {
|
|
|
- ChronoComponent.prototype.setElement.apply(this, arguments);
|
|
|
-
|
|
|
- if (this.hasDayInteractions) {
|
|
|
- preventSelection(el);
|
|
|
-
|
|
|
- this.bindDayHandler('touchstart', this.dayTouchStart);
|
|
|
- this.bindDayHandler('mousedown', this.dayMousedown);
|
|
|
- }
|
|
|
-
|
|
|
- // attach event-element-related handlers. in Grid.events
|
|
|
- // same garbage collection note as above.
|
|
|
- this.bindSegHandlers();
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- bindDayHandler: function(name, handler) {
|
|
|
- var _this = this;
|
|
|
-
|
|
|
- // attach a handler to the grid's root element.
|
|
|
- // jQuery will take care of unregistering them when removeElement gets called.
|
|
|
- this.el.on(name, function(ev) {
|
|
|
- if (
|
|
|
- !$(ev.target).is(
|
|
|
- _this.segSelector + ',' + // directly on an event element
|
|
|
- _this.segSelector + ' *,' + // within an event element
|
|
|
- '.fc-more,' + // a "more.." link
|
|
|
- 'a[data-goto]' // a clickable nav link
|
|
|
- )
|
|
|
- ) {
|
|
|
- return handler.call(_this, ev);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
+ CoordChronoComponent.prototype.unrenderEvents.apply(this, arguments);
|
|
|
|
|
|
- // Removes the grid's container element from the DOM. Undoes any other DOM-related attachments.
|
|
|
- // DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View
|
|
|
- removeElement: function() {
|
|
|
- ChronoComponent.prototype.removeElement.apply(this, arguments);
|
|
|
-
|
|
|
- this.clearDragListeners();
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /* Handlers
|
|
|
- ------------------------------------------------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-
|
|
|
- // Binds DOM handlers to elements that reside outside the grid, such as the document
|
|
|
- bindGlobalHandlers: function() {
|
|
|
- ChronoComponent.prototype.bindGlobalHandlers.apply(this, arguments);
|
|
|
-
|
|
|
- this.listenTo($(document), {
|
|
|
- dragstart: this.externalDragStart, // jqui
|
|
|
- sortstart: this.externalDragStart // jqui
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- // Unbinds DOM handlers from elements that reside outside the grid
|
|
|
- unbindGlobalHandlers: function() {
|
|
|
- ChronoComponent.prototype.unbindGlobalHandlers.apply(this, arguments);
|
|
|
-
|
|
|
- this.stopListeningTo($(document));
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- // Process a mousedown on an element that represents a day. For day clicking and selecting.
|
|
|
- dayMousedown: function(ev) {
|
|
|
-
|
|
|
- // HACK
|
|
|
- // This will still work even though bindDayHandler doesn't use GlobalEmitter.
|
|
|
- if (GlobalEmitter.get().shouldIgnoreMouse()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- this.dayClickListener.startInteraction(ev);
|
|
|
-
|
|
|
- if (this.opt('selectable')) {
|
|
|
- this.daySelectListener.startInteraction(ev, {
|
|
|
- distance: this.opt('selectMinDistance')
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- dayTouchStart: function(ev) {
|
|
|
- var view = this.view;
|
|
|
- var selectLongPressDelay;
|
|
|
-
|
|
|
- // On iOS (and Android?) when a new selection is initiated overtop another selection,
|
|
|
- // the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
|
|
|
- // HACK: simply don't allow this to happen.
|
|
|
- // ALSO: prevent selection when an *event* is already raised.
|
|
|
- if (view.isSelected || view.selectedEvent) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- selectLongPressDelay = this.opt('selectLongPressDelay');
|
|
|
- if (selectLongPressDelay == null) {
|
|
|
- selectLongPressDelay = this.opt('longPressDelay'); // fallback
|
|
|
- }
|
|
|
-
|
|
|
- this.dayClickListener.startInteraction(ev);
|
|
|
-
|
|
|
- if (this.opt('selectable')) {
|
|
|
- this.daySelectListener.startInteraction(ev, {
|
|
|
- delay: selectLongPressDelay
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- // Kills all in-progress dragging.
|
|
|
- // Useful for when public API methods that result in re-rendering are invoked during a drag.
|
|
|
- // Also useful for when touch devices misbehave and don't fire their touchend.
|
|
|
- clearDragListeners: function() {
|
|
|
- this.dayClickListener.endInteraction();
|
|
|
- this.daySelectListener.endInteraction();
|
|
|
-
|
|
|
- if (this.segDragListener) {
|
|
|
- this.segDragListener.endInteraction(); // will clear this.segDragListener
|
|
|
- }
|
|
|
- if (this.segResizeListener) {
|
|
|
- this.segResizeListener.endInteraction(); // will clear this.segResizeListener
|
|
|
- }
|
|
|
- if (this.externalDragListener) {
|
|
|
- this.externalDragListener.endInteraction(); // will clear this.externalDragListener
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /* Converting eventRange -> eventFootprint
|
|
|
- ------------------------------------------------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-
|
|
|
- eventRangesToEventFootprints: function(eventRanges) {
|
|
|
- var eventFootprints = [];
|
|
|
- var i;
|
|
|
-
|
|
|
- for (i = 0; i < eventRanges.length; i++) {
|
|
|
- eventFootprints.push.apply(eventFootprints,
|
|
|
- this.eventRangeToEventFootprints(eventRanges[i])
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- return eventFootprints;
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- // Given an event's unzoned date range, return an array of eventSpan objects.
|
|
|
- // eventSpan - { start, end, isStart, isEnd, otherthings... }
|
|
|
- // Subclasses can override.
|
|
|
- // Subclasses are obligated to forward eventRange.isStart/isEnd to the resulting spans.
|
|
|
- // TODO: somehow more DRY with Calendar::eventRangeToEventFootprints
|
|
|
- eventRangeToEventFootprints: function(eventRange) {
|
|
|
- return [
|
|
|
- new EventFootprint(
|
|
|
- new ComponentFootprint(
|
|
|
- eventRange.unzonedRange,
|
|
|
- eventRange.eventDef.isAllDay()
|
|
|
- ),
|
|
|
- eventRange.eventDef,
|
|
|
- eventRange.eventInstance // might not exist
|
|
|
- )
|
|
|
- ];
|
|
|
+ SegChronoComponentMixin.unrenderEvents.apply(this, arguments);
|
|
|
}
|
|
|
|
|
|
});
|