fullcalendar-rails 2.4.0.0 → 2.4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/fullcalendar-rails.gemspec +1 -1
- data/lib/fullcalendar-rails/version.rb +1 -1
- data/vendor/assets/javascripts/fullcalendar.js +821 -440
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 673dd0676cb4b611063a1934897f589144a61959
|
4
|
+
data.tar.gz: a31d5bb86c88562ba3c2d4df0ec67ba5033ff656
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5ad43a3ddc1113c9e657226456a4167a97a44961887a0eec9697da821c6fd76adb82a082176ba4a129c8dfeee7a793acb9cb6a83849043d841cdb12fdfc2766
|
7
|
+
data.tar.gz: 85e378bb55846a7abdab1a883e539ca80c70133d57542cedfd017e0869603cb306e8082d1bce8983c68cd0b09d22663e792dc369c3b25267269e27b5e600a2d7
|
data/fullcalendar-rails.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Fullcalendar::Rails::VERSION
|
17
17
|
gem.license = 'MIT'
|
18
18
|
|
19
|
-
gem.add_runtime_dependency 'jquery-rails', '>=
|
19
|
+
gem.add_runtime_dependency 'jquery-rails', '>= 4.0.5', '< 5.0.0'
|
20
20
|
gem.add_runtime_dependency 'momentjs-rails', '>= 2.9.0'
|
21
21
|
gem.add_development_dependency 'rake', '~> 0'
|
22
22
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* FullCalendar v2.
|
2
|
+
* FullCalendar v2.4.0
|
3
3
|
* Docs & License: http://fullcalendar.io/
|
4
4
|
* (c) 2015 Adam Shaw
|
5
5
|
*/
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
;;
|
20
20
|
|
21
|
-
var fc = $.fullCalendar = { version: "2.
|
21
|
+
var fc = $.fullCalendar = { version: "2.4.0" };
|
22
22
|
var fcViews = fc.views = {};
|
23
23
|
|
24
24
|
|
@@ -45,7 +45,7 @@ $.fn.fullCalendar = function(options) {
|
|
45
45
|
}
|
46
46
|
// a new calendar initialization
|
47
47
|
else if (!calendar) { // don't initialize twice
|
48
|
-
calendar = new
|
48
|
+
calendar = new Calendar(element, options);
|
49
49
|
element.data('fullCalendar', calendar);
|
50
50
|
calendar.render();
|
51
51
|
}
|
@@ -63,41 +63,9 @@ var complexOptions = [ // names of options that are objects whose properties sho
|
|
63
63
|
];
|
64
64
|
|
65
65
|
|
66
|
-
//
|
67
|
-
|
68
|
-
|
69
|
-
var chain = Array.prototype.slice.call(arguments); // convert to a real array
|
70
|
-
var complexVals = {}; // hash for each complex option's combined values
|
71
|
-
var i, name;
|
72
|
-
var combinedVal;
|
73
|
-
var j;
|
74
|
-
var val;
|
75
|
-
|
76
|
-
// for each complex option, loop through each option-hash and accumulate the combined values
|
77
|
-
for (i = 0; i < complexOptions.length; i++) {
|
78
|
-
name = complexOptions[i];
|
79
|
-
combinedVal = null; // an object holding the merge of all the values
|
80
|
-
|
81
|
-
for (j = 0; j < chain.length; j++) {
|
82
|
-
val = chain[j][name];
|
83
|
-
|
84
|
-
if ($.isPlainObject(val)) {
|
85
|
-
combinedVal = $.extend(combinedVal || {}, val); // merge new properties
|
86
|
-
}
|
87
|
-
else if (val != null) { // a non-null non-undefined atomic option
|
88
|
-
combinedVal = null; // signal to use the atomic value
|
89
|
-
}
|
90
|
-
}
|
91
|
-
|
92
|
-
// if not null, the final value was a combination of other objects. record it
|
93
|
-
if (combinedVal !== null) {
|
94
|
-
complexVals[name] = combinedVal;
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
chain.unshift({}); // $.extend will mutate this with the result
|
99
|
-
chain.push(complexVals); // computed complex values are applied last
|
100
|
-
return $.extend.apply($, chain); // combine
|
66
|
+
// Merges an array of option objects into a single object
|
67
|
+
function mergeOptions(optionObjs) {
|
68
|
+
return mergeProps(optionObjs, complexOptions);
|
101
69
|
}
|
102
70
|
|
103
71
|
|
@@ -160,6 +128,7 @@ fc.isInt = isInt;
|
|
160
128
|
fc.htmlEscape = htmlEscape;
|
161
129
|
fc.cssToStr = cssToStr;
|
162
130
|
fc.proxy = proxy;
|
131
|
+
fc.capitaliseFirstLetter = capitaliseFirstLetter;
|
163
132
|
|
164
133
|
|
165
134
|
/* FullCalendar-specific DOM Utilities
|
@@ -450,6 +419,7 @@ function isPrimaryMouseButton(ev) {
|
|
450
419
|
/* Geometry
|
451
420
|
----------------------------------------------------------------------------------------------------------------------*/
|
452
421
|
|
422
|
+
fc.intersectRects = intersectRects;
|
453
423
|
|
454
424
|
// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
|
455
425
|
function intersectRects(rect1, rect2) {
|
@@ -494,6 +464,90 @@ function diffPoints(point1, point2) {
|
|
494
464
|
}
|
495
465
|
|
496
466
|
|
467
|
+
/* Object Ordering by Field
|
468
|
+
----------------------------------------------------------------------------------------------------------------------*/
|
469
|
+
|
470
|
+
fc.parseFieldSpecs = parseFieldSpecs;
|
471
|
+
fc.compareByFieldSpecs = compareByFieldSpecs;
|
472
|
+
fc.compareByFieldSpec = compareByFieldSpec;
|
473
|
+
fc.flexibleCompare = flexibleCompare;
|
474
|
+
|
475
|
+
|
476
|
+
function parseFieldSpecs(input) {
|
477
|
+
var specs = [];
|
478
|
+
var tokens = [];
|
479
|
+
var i, token;
|
480
|
+
|
481
|
+
if (typeof input === 'string') {
|
482
|
+
tokens = input.split(/\s*,\s*/);
|
483
|
+
}
|
484
|
+
else if (typeof input === 'function') {
|
485
|
+
tokens = [ input ];
|
486
|
+
}
|
487
|
+
else if ($.isArray(input)) {
|
488
|
+
tokens = input;
|
489
|
+
}
|
490
|
+
|
491
|
+
for (i = 0; i < tokens.length; i++) {
|
492
|
+
token = tokens[i];
|
493
|
+
|
494
|
+
if (typeof token === 'string') {
|
495
|
+
specs.push(
|
496
|
+
token.charAt(0) == '-' ?
|
497
|
+
{ field: token.substring(1), order: -1 } :
|
498
|
+
{ field: token, order: 1 }
|
499
|
+
);
|
500
|
+
}
|
501
|
+
else if (typeof token === 'function') {
|
502
|
+
specs.push({ func: token });
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
return specs;
|
507
|
+
}
|
508
|
+
|
509
|
+
|
510
|
+
function compareByFieldSpecs(obj1, obj2, fieldSpecs) {
|
511
|
+
var i;
|
512
|
+
var cmp;
|
513
|
+
|
514
|
+
for (i = 0; i < fieldSpecs.length; i++) {
|
515
|
+
cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i]);
|
516
|
+
if (cmp) {
|
517
|
+
return cmp;
|
518
|
+
}
|
519
|
+
}
|
520
|
+
|
521
|
+
return 0;
|
522
|
+
}
|
523
|
+
|
524
|
+
|
525
|
+
function compareByFieldSpec(obj1, obj2, fieldSpec) {
|
526
|
+
if (fieldSpec.func) {
|
527
|
+
return fieldSpec.func(obj1, obj2);
|
528
|
+
}
|
529
|
+
return flexibleCompare(obj1[fieldSpec.field], obj2[fieldSpec.field]) *
|
530
|
+
(fieldSpec.order || 1);
|
531
|
+
}
|
532
|
+
|
533
|
+
|
534
|
+
function flexibleCompare(a, b) {
|
535
|
+
if (!a && !b) {
|
536
|
+
return 0;
|
537
|
+
}
|
538
|
+
if (b == null) {
|
539
|
+
return -1;
|
540
|
+
}
|
541
|
+
if (a == null) {
|
542
|
+
return 1;
|
543
|
+
}
|
544
|
+
if ($.type(a) === 'string' || $.type(b) === 'string') {
|
545
|
+
return String(a).localeCompare(String(b));
|
546
|
+
}
|
547
|
+
return a - b;
|
548
|
+
}
|
549
|
+
|
550
|
+
|
497
551
|
/* FullCalendar-specific Misc Utilities
|
498
552
|
----------------------------------------------------------------------------------------------------------------------*/
|
499
553
|
|
@@ -543,6 +597,9 @@ function intersectionToSeg(subjectRange, constraintRange) {
|
|
543
597
|
----------------------------------------------------------------------------------------------------------------------*/
|
544
598
|
|
545
599
|
fc.computeIntervalUnit = computeIntervalUnit;
|
600
|
+
fc.divideRangeByDuration = divideRangeByDuration;
|
601
|
+
fc.divideDurationByDuration = divideDurationByDuration;
|
602
|
+
fc.multiplyDuration = multiplyDuration;
|
546
603
|
fc.durationHasTime = durationHasTime;
|
547
604
|
|
548
605
|
var dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
|
@@ -614,6 +671,55 @@ function computeRangeAs(unit, start, end) {
|
|
614
671
|
}
|
615
672
|
|
616
673
|
|
674
|
+
// Intelligently divides a range (specified by a start/end params) by a duration
|
675
|
+
function divideRangeByDuration(start, end, dur) {
|
676
|
+
var months;
|
677
|
+
|
678
|
+
if (durationHasTime(dur)) {
|
679
|
+
return (end - start) / dur;
|
680
|
+
}
|
681
|
+
months = dur.asMonths();
|
682
|
+
if (Math.abs(months) >= 1 && isInt(months)) {
|
683
|
+
return end.diff(start, 'months', true) / months;
|
684
|
+
}
|
685
|
+
return end.diff(start, 'days', true) / dur.asDays();
|
686
|
+
}
|
687
|
+
|
688
|
+
|
689
|
+
// Intelligently divides one duration by another
|
690
|
+
function divideDurationByDuration(dur1, dur2) {
|
691
|
+
var months1, months2;
|
692
|
+
|
693
|
+
if (durationHasTime(dur1) || durationHasTime(dur2)) {
|
694
|
+
return dur1 / dur2;
|
695
|
+
}
|
696
|
+
months1 = dur1.asMonths();
|
697
|
+
months2 = dur2.asMonths();
|
698
|
+
if (
|
699
|
+
Math.abs(months1) >= 1 && isInt(months1) &&
|
700
|
+
Math.abs(months2) >= 1 && isInt(months2)
|
701
|
+
) {
|
702
|
+
return months1 / months2;
|
703
|
+
}
|
704
|
+
return dur1.asDays() / dur2.asDays();
|
705
|
+
}
|
706
|
+
|
707
|
+
|
708
|
+
// Intelligently multiplies a duration by a number
|
709
|
+
function multiplyDuration(dur, n) {
|
710
|
+
var months;
|
711
|
+
|
712
|
+
if (durationHasTime(dur)) {
|
713
|
+
return moment.duration(dur * n);
|
714
|
+
}
|
715
|
+
months = dur.asMonths();
|
716
|
+
if (Math.abs(months) >= 1 && isInt(months)) {
|
717
|
+
return moment.duration({ months: months * n });
|
718
|
+
}
|
719
|
+
return moment.duration({ days: dur.asDays() * n });
|
720
|
+
}
|
721
|
+
|
722
|
+
|
617
723
|
// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)
|
618
724
|
function durationHasTime(dur) {
|
619
725
|
return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds());
|
@@ -631,12 +737,84 @@ function isTimeString(str) {
|
|
631
737
|
}
|
632
738
|
|
633
739
|
|
740
|
+
/* Logging and Debug
|
741
|
+
----------------------------------------------------------------------------------------------------------------------*/
|
742
|
+
|
743
|
+
fc.log = function() {
|
744
|
+
var console = window.console;
|
745
|
+
|
746
|
+
if (console && console.log) {
|
747
|
+
return console.log.apply(console, arguments);
|
748
|
+
}
|
749
|
+
};
|
750
|
+
|
751
|
+
fc.warn = function() {
|
752
|
+
var console = window.console;
|
753
|
+
|
754
|
+
if (console && console.warn) {
|
755
|
+
return console.warn.apply(console, arguments);
|
756
|
+
}
|
757
|
+
else {
|
758
|
+
return fc.log.apply(fc, arguments);
|
759
|
+
}
|
760
|
+
};
|
761
|
+
|
762
|
+
|
634
763
|
/* General Utilities
|
635
764
|
----------------------------------------------------------------------------------------------------------------------*/
|
636
765
|
|
637
766
|
var hasOwnPropMethod = {}.hasOwnProperty;
|
638
767
|
|
639
768
|
|
769
|
+
// Merges an array of objects into a single object.
|
770
|
+
// The second argument allows for an array of property names who's object values will be merged together.
|
771
|
+
function mergeProps(propObjs, complexProps) {
|
772
|
+
var dest = {};
|
773
|
+
var i, name;
|
774
|
+
var complexObjs;
|
775
|
+
var j, val;
|
776
|
+
var props;
|
777
|
+
|
778
|
+
if (complexProps) {
|
779
|
+
for (i = 0; i < complexProps.length; i++) {
|
780
|
+
name = complexProps[i];
|
781
|
+
complexObjs = [];
|
782
|
+
|
783
|
+
// collect the trailing object values, stopping when a non-object is discovered
|
784
|
+
for (j = propObjs.length - 1; j >= 0; j--) {
|
785
|
+
val = propObjs[j][name];
|
786
|
+
|
787
|
+
if (typeof val === 'object') {
|
788
|
+
complexObjs.unshift(val);
|
789
|
+
}
|
790
|
+
else if (val !== undefined) {
|
791
|
+
dest[name] = val; // if there were no objects, this value will be used
|
792
|
+
break;
|
793
|
+
}
|
794
|
+
}
|
795
|
+
|
796
|
+
// if the trailing values were objects, use the merged value
|
797
|
+
if (complexObjs.length) {
|
798
|
+
dest[name] = mergeProps(complexObjs);
|
799
|
+
}
|
800
|
+
}
|
801
|
+
}
|
802
|
+
|
803
|
+
// copy values into the destination, going from last to first
|
804
|
+
for (i = propObjs.length - 1; i >= 0; i--) {
|
805
|
+
props = propObjs[i];
|
806
|
+
|
807
|
+
for (name in props) {
|
808
|
+
if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
|
809
|
+
dest[name] = props[name];
|
810
|
+
}
|
811
|
+
}
|
812
|
+
}
|
813
|
+
|
814
|
+
return dest;
|
815
|
+
}
|
816
|
+
|
817
|
+
|
640
818
|
// Create an object that has the given prototype. Just like Object.create
|
641
819
|
function createObject(proto) {
|
642
820
|
var f = function() {};
|
@@ -1570,10 +1748,63 @@ Class.extend = function(members) {
|
|
1570
1748
|
// adds new member variables/methods to the class's prototype.
|
1571
1749
|
// can be called with another class, or a plain object hash containing new members.
|
1572
1750
|
Class.mixin = function(members) {
|
1573
|
-
copyOwnProps(members.prototype || members, this.prototype);
|
1751
|
+
copyOwnProps(members.prototype || members, this.prototype); // TODO: copyNativeMethods?
|
1574
1752
|
};
|
1575
1753
|
;;
|
1576
1754
|
|
1755
|
+
var Emitter = fc.Emitter = Class.extend({
|
1756
|
+
|
1757
|
+
callbackHash: null,
|
1758
|
+
|
1759
|
+
|
1760
|
+
on: function(name, callback) {
|
1761
|
+
this.getCallbacks(name).add(callback);
|
1762
|
+
return this; // for chaining
|
1763
|
+
},
|
1764
|
+
|
1765
|
+
|
1766
|
+
off: function(name, callback) {
|
1767
|
+
this.getCallbacks(name).remove(callback);
|
1768
|
+
return this; // for chaining
|
1769
|
+
},
|
1770
|
+
|
1771
|
+
|
1772
|
+
trigger: function(name) { // args...
|
1773
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
1774
|
+
|
1775
|
+
this.triggerWith(name, this, args);
|
1776
|
+
|
1777
|
+
return this; // for chaining
|
1778
|
+
},
|
1779
|
+
|
1780
|
+
|
1781
|
+
triggerWith: function(name, context, args) {
|
1782
|
+
var callbacks = this.getCallbacks(name);
|
1783
|
+
|
1784
|
+
callbacks.fireWith(context, args);
|
1785
|
+
|
1786
|
+
return this; // for chaining
|
1787
|
+
},
|
1788
|
+
|
1789
|
+
|
1790
|
+
getCallbacks: function(name) {
|
1791
|
+
var callbacks;
|
1792
|
+
|
1793
|
+
if (!this.callbackHash) {
|
1794
|
+
this.callbackHash = {};
|
1795
|
+
}
|
1796
|
+
|
1797
|
+
callbacks = this.callbackHash[name];
|
1798
|
+
if (!callbacks) {
|
1799
|
+
callbacks = this.callbackHash[name] = $.Callbacks();
|
1800
|
+
}
|
1801
|
+
|
1802
|
+
return callbacks;
|
1803
|
+
}
|
1804
|
+
|
1805
|
+
});
|
1806
|
+
;;
|
1807
|
+
|
1577
1808
|
/* A rectangular panel that is absolutely positioned over other content
|
1578
1809
|
------------------------------------------------------------------------------------------------------------------------
|
1579
1810
|
Options:
|
@@ -1662,7 +1893,7 @@ var Popover = Class.extend({
|
|
1662
1893
|
|
1663
1894
|
|
1664
1895
|
// Hides and unregisters any handlers
|
1665
|
-
|
1896
|
+
removeElement: function() {
|
1666
1897
|
this.hide();
|
1667
1898
|
|
1668
1899
|
if (this.el) {
|
@@ -1774,6 +2005,7 @@ var GridCoordMap = Class.extend({
|
|
1774
2005
|
|
1775
2006
|
// Queries the grid for the coordinates of all the cells
|
1776
2007
|
build: function() {
|
2008
|
+
this.grid.build();
|
1777
2009
|
this.rowCoords = this.grid.computeRowCoords();
|
1778
2010
|
this.colCoords = this.grid.computeColCoords();
|
1779
2011
|
this.computeBounds();
|
@@ -1782,6 +2014,7 @@ var GridCoordMap = Class.extend({
|
|
1782
2014
|
|
1783
2015
|
// Clears the coordinates data to free up memory
|
1784
2016
|
clear: function() {
|
2017
|
+
this.grid.clear();
|
1785
2018
|
this.rowCoords = null;
|
1786
2019
|
this.colCoords = null;
|
1787
2020
|
},
|
@@ -2549,7 +2782,7 @@ var MouseFollower = Class.extend({
|
|
2549
2782
|
|
2550
2783
|
function complete() {
|
2551
2784
|
this.isAnimating = false;
|
2552
|
-
_this.
|
2785
|
+
_this.removeElement();
|
2553
2786
|
|
2554
2787
|
this.top0 = this.left0 = null; // reset state for future updatePosition calls
|
2555
2788
|
|
@@ -2607,7 +2840,7 @@ var MouseFollower = Class.extend({
|
|
2607
2840
|
|
2608
2841
|
|
2609
2842
|
// Removes the tracking element if it has already been created
|
2610
|
-
|
2843
|
+
removeElement: function() {
|
2611
2844
|
if (this.el) {
|
2612
2845
|
this.el.remove();
|
2613
2846
|
this.el = null;
|
@@ -2787,8 +3020,6 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
2787
3020
|
|
2788
3021
|
rowCnt: 0, // number of rows
|
2789
3022
|
colCnt: 0, // number of cols
|
2790
|
-
rowData: null, // array of objects, holding misc data for each row
|
2791
|
-
colData: null, // array of objects, holding misc data for each column
|
2792
3023
|
|
2793
3024
|
el: null, // the containing element
|
2794
3025
|
coordMap: null, // a GridCoordMap that converts pixel values to datetimes
|
@@ -2854,18 +3085,27 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
2854
3085
|
------------------------------------------------------------------------------------------------------------------*/
|
2855
3086
|
|
2856
3087
|
|
2857
|
-
// Tells the grid about what period of time to display.
|
3088
|
+
// Tells the grid about what period of time to display.
|
3089
|
+
// Any date-related cell system internal data should be generated.
|
2858
3090
|
setRange: function(range) {
|
2859
|
-
var view = this.view;
|
2860
|
-
var displayEventTime;
|
2861
|
-
var displayEventEnd;
|
2862
|
-
|
2863
3091
|
this.start = range.start.clone();
|
2864
3092
|
this.end = range.end.clone();
|
2865
3093
|
|
2866
|
-
this.
|
2867
|
-
this.
|
2868
|
-
|
3094
|
+
this.rangeUpdated();
|
3095
|
+
this.processRangeOptions();
|
3096
|
+
},
|
3097
|
+
|
3098
|
+
|
3099
|
+
// Called when internal variables that rely on the range should be updated
|
3100
|
+
rangeUpdated: function() {
|
3101
|
+
},
|
3102
|
+
|
3103
|
+
|
3104
|
+
// Updates values that rely on options and also relate to range
|
3105
|
+
processRangeOptions: function() {
|
3106
|
+
var view = this.view;
|
3107
|
+
var displayEventTime;
|
3108
|
+
var displayEventEnd;
|
2869
3109
|
|
2870
3110
|
// Populate option-derived settings. Look for override first, then compute if necessary.
|
2871
3111
|
this.colHeadFormat = view.opt('columnFormat') || this.computeColHeadFormat();
|
@@ -2890,9 +3130,15 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
2890
3130
|
},
|
2891
3131
|
|
2892
3132
|
|
2893
|
-
//
|
2894
|
-
|
2895
|
-
|
3133
|
+
// Called before the grid's coordinates will need to be queried for cells.
|
3134
|
+
// Any non-date-related cell system internal data should be built.
|
3135
|
+
build: function() {
|
3136
|
+
},
|
3137
|
+
|
3138
|
+
|
3139
|
+
// Called after the grid's coordinates are done being relied upon.
|
3140
|
+
// Any non-date-related cell system internal data should be cleared.
|
3141
|
+
clear: function() {
|
2896
3142
|
},
|
2897
3143
|
|
2898
3144
|
|
@@ -2964,13 +3210,13 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
2964
3210
|
|
2965
3211
|
// Retrieves misc data about the given row
|
2966
3212
|
getRowData: function(row) {
|
2967
|
-
return
|
3213
|
+
return {};
|
2968
3214
|
},
|
2969
3215
|
|
2970
3216
|
|
2971
3217
|
// Retrieves misc data baout the given column
|
2972
3218
|
getColData: function(col) {
|
2973
|
-
return
|
3219
|
+
return {};
|
2974
3220
|
},
|
2975
3221
|
|
2976
3222
|
|
@@ -3067,7 +3313,7 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3067
3313
|
|
3068
3314
|
|
3069
3315
|
// Removes the grid's container element from the DOM. Undoes any other DOM-related attachments.
|
3070
|
-
// DOES NOT remove any content
|
3316
|
+
// DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View
|
3071
3317
|
removeElement: function() {
|
3072
3318
|
this.unbindGlobalHandlers();
|
3073
3319
|
|
@@ -3091,7 +3337,7 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3091
3337
|
|
3092
3338
|
|
3093
3339
|
// Unrenders the grid's date-related content
|
3094
|
-
|
3340
|
+
unrenderDates: function() {
|
3095
3341
|
// subclasses should implement
|
3096
3342
|
},
|
3097
3343
|
|
@@ -3146,12 +3392,12 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3146
3392
|
cellOut: function(cell) {
|
3147
3393
|
dayClickCell = null;
|
3148
3394
|
selectionRange = null;
|
3149
|
-
_this.
|
3395
|
+
_this.unrenderSelection();
|
3150
3396
|
enableCursor();
|
3151
3397
|
},
|
3152
3398
|
listenStop: function(ev) {
|
3153
3399
|
if (dayClickCell) {
|
3154
|
-
view.
|
3400
|
+
view.triggerDayClick(dayClickCell, _this.getCellDayEl(dayClickCell), ev);
|
3155
3401
|
}
|
3156
3402
|
if (selectionRange) {
|
3157
3403
|
// the selection will already have been rendered. just report it
|
@@ -3208,7 +3454,7 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3208
3454
|
|
3209
3455
|
|
3210
3456
|
// Unrenders a mock event
|
3211
|
-
|
3457
|
+
unrenderHelper: function() {
|
3212
3458
|
// subclasses must implement
|
3213
3459
|
},
|
3214
3460
|
|
@@ -3219,13 +3465,13 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3219
3465
|
|
3220
3466
|
// Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses.
|
3221
3467
|
renderSelection: function(range) {
|
3222
|
-
this.renderHighlight(range);
|
3468
|
+
this.renderHighlight(this.selectionRangeToSegs(range));
|
3223
3469
|
},
|
3224
3470
|
|
3225
3471
|
|
3226
3472
|
// Unrenders any visual indications of a selection. Will unrender a highlight by default.
|
3227
|
-
|
3228
|
-
this.
|
3473
|
+
unrenderSelection: function() {
|
3474
|
+
this.unrenderHighlight();
|
3229
3475
|
},
|
3230
3476
|
|
3231
3477
|
|
@@ -3256,19 +3502,24 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3256
3502
|
},
|
3257
3503
|
|
3258
3504
|
|
3505
|
+
selectionRangeToSegs: function(range) {
|
3506
|
+
return this.rangeToSegs(range);
|
3507
|
+
},
|
3508
|
+
|
3509
|
+
|
3259
3510
|
/* Highlight
|
3260
3511
|
------------------------------------------------------------------------------------------------------------------*/
|
3261
3512
|
|
3262
3513
|
|
3263
|
-
// Renders an emphasis on the given date range.
|
3264
|
-
renderHighlight: function(
|
3265
|
-
this.renderFill('highlight',
|
3514
|
+
// Renders an emphasis on the given date range. Given an array of segments.
|
3515
|
+
renderHighlight: function(segs) {
|
3516
|
+
this.renderFill('highlight', segs);
|
3266
3517
|
},
|
3267
3518
|
|
3268
3519
|
|
3269
3520
|
// Unrenders the emphasis on a date range
|
3270
|
-
|
3271
|
-
this.
|
3521
|
+
unrenderHighlight: function() {
|
3522
|
+
this.unrenderFill('highlight');
|
3272
3523
|
},
|
3273
3524
|
|
3274
3525
|
|
@@ -3283,7 +3534,7 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3283
3534
|
|
3284
3535
|
|
3285
3536
|
// Renders a set of rectangles over the given segments of time.
|
3286
|
-
//
|
3537
|
+
// MUST RETURN a subset of segs, the segs that were actually rendered.
|
3287
3538
|
// Responsible for populating this.elsByFill. TODO: better API for expressing this requirement
|
3288
3539
|
renderFill: function(type, segs) {
|
3289
3540
|
// subclasses must implement
|
@@ -3291,7 +3542,7 @@ var Grid = fc.Grid = RowRenderer.extend({
|
|
3291
3542
|
|
3292
3543
|
|
3293
3544
|
// Unrenders a specific type of fill that is currently rendered on the grid
|
3294
|
-
|
3545
|
+
unrenderFill: function(type) {
|
3295
3546
|
var el = this.elsByFill[type];
|
3296
3547
|
|
3297
3548
|
if (el) {
|
@@ -3484,11 +3735,11 @@ Grid.mixin({
|
|
3484
3735
|
|
3485
3736
|
|
3486
3737
|
// Unrenders all events currently rendered on the grid
|
3487
|
-
|
3738
|
+
unrenderEvents: function() {
|
3488
3739
|
this.triggerSegMouseout(); // trigger an eventMouseout if user's mouse is over an event
|
3489
3740
|
|
3490
|
-
this.
|
3491
|
-
this.
|
3741
|
+
this.unrenderFgSegs();
|
3742
|
+
this.unrenderBgSegs();
|
3492
3743
|
|
3493
3744
|
this.segs = null;
|
3494
3745
|
},
|
@@ -3511,7 +3762,7 @@ Grid.mixin({
|
|
3511
3762
|
|
3512
3763
|
|
3513
3764
|
// Unrenders all currently rendered foreground segments
|
3514
|
-
|
3765
|
+
unrenderFgSegs: function() {
|
3515
3766
|
// subclasses must implement
|
3516
3767
|
},
|
3517
3768
|
|
@@ -3568,8 +3819,8 @@ Grid.mixin({
|
|
3568
3819
|
|
3569
3820
|
|
3570
3821
|
// Unrenders all the currently rendered background event segments
|
3571
|
-
|
3572
|
-
this.
|
3822
|
+
unrenderBgSegs: function() {
|
3823
|
+
this.unrenderFill('bgEvent');
|
3573
3824
|
},
|
3574
3825
|
|
3575
3826
|
|
@@ -3749,7 +4000,7 @@ Grid.mixin({
|
|
3749
4000
|
}
|
3750
4001
|
},
|
3751
4002
|
cellOut: function() { // called before mouse moves to a different cell OR moved out of all cells
|
3752
|
-
view.
|
4003
|
+
view.unrenderDrag(); // unrender whatever was done in renderDrag
|
3753
4004
|
mouseFollower.show(); // show in case we are moving out of all cells
|
3754
4005
|
dropLocation = null;
|
3755
4006
|
},
|
@@ -3759,7 +4010,7 @@ Grid.mixin({
|
|
3759
4010
|
dragStop: function(ev) {
|
3760
4011
|
// do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
|
3761
4012
|
mouseFollower.stop(!dropLocation, function() {
|
3762
|
-
view.
|
4013
|
+
view.unrenderDrag();
|
3763
4014
|
view.showEvent(event);
|
3764
4015
|
_this.segDragStop(seg, ev);
|
3765
4016
|
|
@@ -3903,11 +4154,11 @@ Grid.mixin({
|
|
3903
4154
|
},
|
3904
4155
|
cellOut: function() {
|
3905
4156
|
dropLocation = null; // signal unsuccessful
|
3906
|
-
_this.
|
4157
|
+
_this.unrenderDrag();
|
3907
4158
|
enableCursor();
|
3908
4159
|
},
|
3909
4160
|
dragStop: function() {
|
3910
|
-
_this.
|
4161
|
+
_this.unrenderDrag();
|
3911
4162
|
enableCursor();
|
3912
4163
|
|
3913
4164
|
if (dropLocation) { // element was dropped on a valid date/time cell
|
@@ -3964,7 +4215,7 @@ Grid.mixin({
|
|
3964
4215
|
|
3965
4216
|
|
3966
4217
|
// Unrenders a visual indication of an event or external element being dragged
|
3967
|
-
|
4218
|
+
unrenderDrag: function() {
|
3968
4219
|
// subclasses must implement
|
3969
4220
|
},
|
3970
4221
|
|
@@ -4019,7 +4270,7 @@ Grid.mixin({
|
|
4019
4270
|
resizeLocation = null;
|
4020
4271
|
},
|
4021
4272
|
cellDone: function() { // resets the rendering to show the original event
|
4022
|
-
_this.
|
4273
|
+
_this.unrenderEventResize();
|
4023
4274
|
view.showEvent(event);
|
4024
4275
|
enableCursor();
|
4025
4276
|
},
|
@@ -4118,7 +4369,7 @@ Grid.mixin({
|
|
4118
4369
|
|
4119
4370
|
|
4120
4371
|
// Unrenders a visual indication of an event being resized.
|
4121
|
-
|
4372
|
+
unrenderEventResize: function() {
|
4122
4373
|
// subclasses must implement
|
4123
4374
|
},
|
4124
4375
|
|
@@ -4334,6 +4585,8 @@ Grid.mixin({
|
|
4334
4585
|
var segs;
|
4335
4586
|
var i, seg;
|
4336
4587
|
|
4588
|
+
eventRange = this.view.calendar.ensureVisibleEventRange(eventRange);
|
4589
|
+
|
4337
4590
|
if (rangeToSegsFunc) {
|
4338
4591
|
segs = rangeToSegsFunc(eventRange);
|
4339
4592
|
}
|
@@ -4349,6 +4602,21 @@ Grid.mixin({
|
|
4349
4602
|
}
|
4350
4603
|
|
4351
4604
|
return segs;
|
4605
|
+
},
|
4606
|
+
|
4607
|
+
|
4608
|
+
sortSegs: function(segs) {
|
4609
|
+
segs.sort(proxy(this, 'compareSegs'));
|
4610
|
+
},
|
4611
|
+
|
4612
|
+
|
4613
|
+
// A cmp function for determining which segments should take visual priority
|
4614
|
+
// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS
|
4615
|
+
compareSegs: function(seg1, seg2) {
|
4616
|
+
return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
|
4617
|
+
seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
|
4618
|
+
seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
|
4619
|
+
compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);
|
4352
4620
|
}
|
4353
4621
|
|
4354
4622
|
});
|
@@ -4393,18 +4661,6 @@ function compareNormalRanges(range1, range2) {
|
|
4393
4661
|
}
|
4394
4662
|
|
4395
4663
|
|
4396
|
-
// A cmp function for determining which segments should take visual priority
|
4397
|
-
// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS
|
4398
|
-
function compareSegs(seg1, seg2) {
|
4399
|
-
return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
|
4400
|
-
seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
|
4401
|
-
seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
|
4402
|
-
(seg1.event.title || '').localeCompare(seg2.event.title); // tie? alphabetically by title
|
4403
|
-
}
|
4404
|
-
|
4405
|
-
fc.compareSegs = compareSegs; // export
|
4406
|
-
|
4407
|
-
|
4408
4664
|
/* External-Dragging-Element Data
|
4409
4665
|
----------------------------------------------------------------------------------------------------------------------*/
|
4410
4666
|
|
@@ -4513,8 +4769,8 @@ var DayGrid = Grid.extend({
|
|
4513
4769
|
},
|
4514
4770
|
|
4515
4771
|
|
4516
|
-
|
4517
|
-
this.
|
4772
|
+
unrenderDates: function() {
|
4773
|
+
this.removeSegPopover();
|
4518
4774
|
},
|
4519
4775
|
|
4520
4776
|
|
@@ -4598,8 +4854,7 @@ var DayGrid = Grid.extend({
|
|
4598
4854
|
------------------------------------------------------------------------------------------------------------------*/
|
4599
4855
|
|
4600
4856
|
|
4601
|
-
|
4602
|
-
updateCells: function() {
|
4857
|
+
rangeUpdated: function() {
|
4603
4858
|
var cellDates;
|
4604
4859
|
var firstDay;
|
4605
4860
|
var rowCnt;
|
@@ -4782,9 +5037,7 @@ var DayGrid = Grid.extend({
|
|
4782
5037
|
renderDrag: function(dropLocation, seg) {
|
4783
5038
|
|
4784
5039
|
// always render a highlight underneath
|
4785
|
-
this.renderHighlight(
|
4786
|
-
this.view.calendar.ensureVisibleEventRange(dropLocation) // needs to be a proper range
|
4787
|
-
);
|
5040
|
+
this.renderHighlight(this.eventRangeToSegs(dropLocation));
|
4788
5041
|
|
4789
5042
|
// if a segment from the same calendar but another component is being dragged, render a helper event
|
4790
5043
|
if (seg && !seg.el.closest(this.el).length) {
|
@@ -4798,9 +5051,9 @@ var DayGrid = Grid.extend({
|
|
4798
5051
|
|
4799
5052
|
|
4800
5053
|
// Unrenders any visual indication of a hovering event
|
4801
|
-
|
4802
|
-
this.
|
4803
|
-
this.
|
5054
|
+
unrenderDrag: function() {
|
5055
|
+
this.unrenderHighlight();
|
5056
|
+
this.unrenderHelper();
|
4804
5057
|
},
|
4805
5058
|
|
4806
5059
|
|
@@ -4810,15 +5063,15 @@ var DayGrid = Grid.extend({
|
|
4810
5063
|
|
4811
5064
|
// Renders a visual indication of an event being resized
|
4812
5065
|
renderEventResize: function(range, seg) {
|
4813
|
-
this.renderHighlight(range);
|
5066
|
+
this.renderHighlight(this.eventRangeToSegs(range));
|
4814
5067
|
this.renderRangeHelper(range, seg);
|
4815
5068
|
},
|
4816
5069
|
|
4817
5070
|
|
4818
5071
|
// Unrenders a visual indication of an event being resized
|
4819
|
-
|
4820
|
-
this.
|
4821
|
-
this.
|
5072
|
+
unrenderEventResize: function() {
|
5073
|
+
this.unrenderHighlight();
|
5074
|
+
this.unrenderHelper();
|
4822
5075
|
},
|
4823
5076
|
|
4824
5077
|
|
@@ -4862,7 +5115,7 @@ var DayGrid = Grid.extend({
|
|
4862
5115
|
|
4863
5116
|
|
4864
5117
|
// Unrenders any visual indication of a mock helper event
|
4865
|
-
|
5118
|
+
unrenderHelper: function() {
|
4866
5119
|
if (this.helperEls) {
|
4867
5120
|
this.helperEls.remove();
|
4868
5121
|
this.helperEls = null;
|
@@ -4946,9 +5199,9 @@ DayGrid.mixin({
|
|
4946
5199
|
|
4947
5200
|
|
4948
5201
|
// Unrenders all events currently rendered on the grid
|
4949
|
-
|
4950
|
-
this.
|
4951
|
-
Grid.prototype.
|
5202
|
+
unrenderEvents: function() {
|
5203
|
+
this.removeSegPopover(); // removes the "more.." events popover
|
5204
|
+
Grid.prototype.unrenderEvents.apply(this, arguments); // calls the super-method
|
4952
5205
|
},
|
4953
5206
|
|
4954
5207
|
|
@@ -4993,7 +5246,7 @@ DayGrid.mixin({
|
|
4993
5246
|
|
4994
5247
|
|
4995
5248
|
// Unrenders all currently rendered foreground event segments
|
4996
|
-
|
5249
|
+
unrenderFgSegs: function() {
|
4997
5250
|
var rowStructs = this.rowStructs || [];
|
4998
5251
|
var rowStruct;
|
4999
5252
|
|
@@ -5183,7 +5436,7 @@ DayGrid.mixin({
|
|
5183
5436
|
|
5184
5437
|
// Give preference to elements with certain criteria, so they have
|
5185
5438
|
// a chance to be closer to the top.
|
5186
|
-
|
5439
|
+
this.sortSegs(segs);
|
5187
5440
|
|
5188
5441
|
for (i = 0; i < segs.length; i++) {
|
5189
5442
|
seg = segs[i];
|
@@ -5265,9 +5518,9 @@ DayGrid.mixin({
|
|
5265
5518
|
popoverSegs: null, // an array of segment objects that the segPopover holds. null when not visible
|
5266
5519
|
|
5267
5520
|
|
5268
|
-
|
5521
|
+
removeSegPopover: function() {
|
5269
5522
|
if (this.segPopover) {
|
5270
|
-
this.segPopover.hide(); //
|
5523
|
+
this.segPopover.hide(); // in handler, will call segPopover's removeElement
|
5271
5524
|
}
|
5272
5525
|
},
|
5273
5526
|
|
@@ -5502,8 +5755,8 @@ DayGrid.mixin({
|
|
5502
5755
|
autoHide: true, // when the user clicks elsewhere, hide the popover
|
5503
5756
|
viewportConstrain: view.opt('popoverViewportConstrain'),
|
5504
5757
|
hide: function() {
|
5505
|
-
//
|
5506
|
-
_this.segPopover.
|
5758
|
+
// kill everything when the popover is hidden
|
5759
|
+
_this.segPopover.removeElement();
|
5507
5760
|
_this.segPopover = null;
|
5508
5761
|
_this.popoverSegs = null;
|
5509
5762
|
}
|
@@ -5584,7 +5837,7 @@ DayGrid.mixin({
|
|
5584
5837
|
);
|
5585
5838
|
|
5586
5839
|
// force an order because eventsToSegs doesn't guarantee one
|
5587
|
-
|
5840
|
+
this.sortSegs(segs);
|
5588
5841
|
|
5589
5842
|
return segs;
|
5590
5843
|
},
|
@@ -5633,11 +5886,11 @@ var TimeGrid = Grid.extend({
|
|
5633
5886
|
|
5634
5887
|
slotDuration: null, // duration of a "slot", a distinct time segment on given day, visualized by lines
|
5635
5888
|
snapDuration: null, // granularity of time for dragging and selecting
|
5636
|
-
|
5637
5889
|
minTime: null, // Duration object that denotes the first visible time of any given day
|
5638
5890
|
maxTime: null, // Duration object that denotes the exclusive visible end time of any given day
|
5639
|
-
|
5640
|
-
|
5891
|
+
colDates: null, // whole-day dates for each column. left to right
|
5892
|
+
labelFormat: null, // formatting string for times running along vertical axis
|
5893
|
+
labelInterval: null, // duration of how often a label should be displayed for a slot
|
5641
5894
|
|
5642
5895
|
dayEls: null, // cells elements in the day-row background
|
5643
5896
|
slatEls: null, // elements running horizontally across all columns
|
@@ -5698,29 +5951,28 @@ var TimeGrid = Grid.extend({
|
|
5698
5951
|
var view = this.view;
|
5699
5952
|
var isRTL = this.isRTL;
|
5700
5953
|
var html = '';
|
5701
|
-
var slotNormal = this.slotDuration.asMinutes() % 15 === 0;
|
5702
5954
|
var slotTime = moment.duration(+this.minTime); // wish there was .clone() for durations
|
5703
5955
|
var slotDate; // will be on the view's first day, but we only care about its time
|
5704
|
-
var
|
5956
|
+
var isLabeled;
|
5705
5957
|
var axisHtml;
|
5706
5958
|
|
5707
5959
|
// Calculate the time for each slot
|
5708
5960
|
while (slotTime < this.maxTime) {
|
5709
|
-
slotDate = this.start.clone().time(slotTime); // will be in UTC but that's good
|
5710
|
-
|
5961
|
+
slotDate = this.start.clone().time(slotTime); // after .time() will be in UTC. but that's good, avoids DST issues
|
5962
|
+
isLabeled = isInt(divideDurationByDuration(slotTime, this.labelInterval));
|
5711
5963
|
|
5712
5964
|
axisHtml =
|
5713
5965
|
'<td class="fc-axis fc-time ' + view.widgetContentClass + '" ' + view.axisStyleAttr() + '>' +
|
5714
|
-
(
|
5966
|
+
(isLabeled ?
|
5715
5967
|
'<span>' + // for matchCellWidths
|
5716
|
-
htmlEscape(slotDate.format(this.
|
5968
|
+
htmlEscape(slotDate.format(this.labelFormat)) +
|
5717
5969
|
'</span>' :
|
5718
5970
|
''
|
5719
5971
|
) +
|
5720
5972
|
'</td>';
|
5721
5973
|
|
5722
5974
|
html +=
|
5723
|
-
'<tr ' + (
|
5975
|
+
'<tr ' + (isLabeled ? '' : 'class="fc-minor"') + '>' +
|
5724
5976
|
(!isRTL ? axisHtml : '') +
|
5725
5977
|
'<td class="' + view.widgetContentClass + '"/>' +
|
5726
5978
|
(isRTL ? axisHtml : '') +
|
@@ -5742,6 +5994,7 @@ var TimeGrid = Grid.extend({
|
|
5742
5994
|
var view = this.view;
|
5743
5995
|
var slotDuration = view.opt('slotDuration');
|
5744
5996
|
var snapDuration = view.opt('snapDuration');
|
5997
|
+
var input;
|
5745
5998
|
|
5746
5999
|
slotDuration = moment.duration(slotDuration);
|
5747
6000
|
snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
|
@@ -5753,7 +6006,41 @@ var TimeGrid = Grid.extend({
|
|
5753
6006
|
this.minTime = moment.duration(view.opt('minTime'));
|
5754
6007
|
this.maxTime = moment.duration(view.opt('maxTime'));
|
5755
6008
|
|
5756
|
-
|
6009
|
+
// might be an array value (for TimelineView).
|
6010
|
+
// if so, getting the most granular entry (the last one probably).
|
6011
|
+
input = view.opt('slotLabelFormat');
|
6012
|
+
if ($.isArray(input)) {
|
6013
|
+
input = input[input.length - 1];
|
6014
|
+
}
|
6015
|
+
|
6016
|
+
this.labelFormat =
|
6017
|
+
input ||
|
6018
|
+
view.opt('axisFormat') || // deprecated
|
6019
|
+
view.opt('smallTimeFormat'); // the computed default
|
6020
|
+
|
6021
|
+
input = view.opt('slotLabelInterval');
|
6022
|
+
this.labelInterval = input ?
|
6023
|
+
moment.duration(input) :
|
6024
|
+
this.computeLabelInterval(slotDuration);
|
6025
|
+
},
|
6026
|
+
|
6027
|
+
|
6028
|
+
// Computes an automatic value for slotLabelInterval
|
6029
|
+
computeLabelInterval: function(slotDuration) {
|
6030
|
+
var i;
|
6031
|
+
var labelInterval;
|
6032
|
+
var slotsPerLabel;
|
6033
|
+
|
6034
|
+
// find the smallest stock label interval that results in more than one slots-per-label
|
6035
|
+
for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
|
6036
|
+
labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
|
6037
|
+
slotsPerLabel = divideDurationByDuration(labelInterval, slotDuration);
|
6038
|
+
if (isInt(slotsPerLabel) && slotsPerLabel > 1) {
|
6039
|
+
return labelInterval;
|
6040
|
+
}
|
6041
|
+
}
|
6042
|
+
|
6043
|
+
return moment.duration(slotDuration); // fall back. clone
|
5757
6044
|
},
|
5758
6045
|
|
5759
6046
|
|
@@ -5784,36 +6071,37 @@ var TimeGrid = Grid.extend({
|
|
5784
6071
|
------------------------------------------------------------------------------------------------------------------*/
|
5785
6072
|
|
5786
6073
|
|
5787
|
-
|
5788
|
-
updateCells: function() {
|
6074
|
+
rangeUpdated: function() {
|
5789
6075
|
var view = this.view;
|
5790
|
-
var
|
6076
|
+
var colDates = [];
|
5791
6077
|
var date;
|
5792
6078
|
|
5793
6079
|
date = this.start.clone();
|
5794
6080
|
while (date.isBefore(this.end)) {
|
5795
|
-
|
5796
|
-
day: date.clone()
|
5797
|
-
});
|
6081
|
+
colDates.push(date.clone());
|
5798
6082
|
date.add(1, 'day');
|
5799
6083
|
date = view.skipHiddenDays(date);
|
5800
6084
|
}
|
5801
6085
|
|
5802
6086
|
if (this.isRTL) {
|
5803
|
-
|
6087
|
+
colDates.reverse();
|
5804
6088
|
}
|
5805
6089
|
|
5806
|
-
this.
|
5807
|
-
this.colCnt =
|
6090
|
+
this.colDates = colDates;
|
6091
|
+
this.colCnt = colDates.length;
|
5808
6092
|
this.rowCnt = Math.ceil((this.maxTime - this.minTime) / this.snapDuration); // # of vertical snaps
|
5809
6093
|
},
|
5810
6094
|
|
5811
6095
|
|
5812
6096
|
// Given a cell object, generates its start date. Returns a reference-free copy.
|
5813
6097
|
computeCellDate: function(cell) {
|
6098
|
+
var date = this.colDates[cell.col];
|
5814
6099
|
var time = this.computeSnapTime(cell.row);
|
5815
6100
|
|
5816
|
-
|
6101
|
+
date = this.view.calendar.rezoneDate(date); // give it a 00:00 time
|
6102
|
+
date.time(time);
|
6103
|
+
|
6104
|
+
return date;
|
5817
6105
|
},
|
5818
6106
|
|
5819
6107
|
|
@@ -5849,7 +6137,7 @@ var TimeGrid = Grid.extend({
|
|
5849
6137
|
};
|
5850
6138
|
|
5851
6139
|
for (col = 0; col < colCnt; col++) {
|
5852
|
-
colDate = this.
|
6140
|
+
colDate = this.colDates[col]; // will be ambig time/timezone
|
5853
6141
|
colRange = {
|
5854
6142
|
start: colDate.clone().time(this.minTime),
|
5855
6143
|
end: colDate.clone().time(this.maxTime)
|
@@ -5971,17 +6259,15 @@ var TimeGrid = Grid.extend({
|
|
5971
6259
|
}
|
5972
6260
|
else {
|
5973
6261
|
// otherwise, just render a highlight
|
5974
|
-
this.renderHighlight(
|
5975
|
-
this.view.calendar.ensureVisibleEventRange(dropLocation) // needs to be a proper range
|
5976
|
-
);
|
6262
|
+
this.renderHighlight(this.eventRangeToSegs(dropLocation));
|
5977
6263
|
}
|
5978
6264
|
},
|
5979
6265
|
|
5980
6266
|
|
5981
6267
|
// Unrenders any visual indication of an event being dragged
|
5982
|
-
|
5983
|
-
this.
|
5984
|
-
this.
|
6268
|
+
unrenderDrag: function() {
|
6269
|
+
this.unrenderHelper();
|
6270
|
+
this.unrenderHighlight();
|
5985
6271
|
},
|
5986
6272
|
|
5987
6273
|
|
@@ -5996,8 +6282,8 @@ var TimeGrid = Grid.extend({
|
|
5996
6282
|
|
5997
6283
|
|
5998
6284
|
// Unrenders any visual indication of an event being resized
|
5999
|
-
|
6000
|
-
this.
|
6285
|
+
unrenderEventResize: function() {
|
6286
|
+
this.unrenderHelper();
|
6001
6287
|
},
|
6002
6288
|
|
6003
6289
|
|
@@ -6036,7 +6322,7 @@ var TimeGrid = Grid.extend({
|
|
6036
6322
|
|
6037
6323
|
|
6038
6324
|
// Unrenders any mock helper event
|
6039
|
-
|
6325
|
+
unrenderHelper: function() {
|
6040
6326
|
if (this.helperEl) {
|
6041
6327
|
this.helperEl.remove();
|
6042
6328
|
this.helperEl = null;
|
@@ -6054,15 +6340,15 @@ var TimeGrid = Grid.extend({
|
|
6054
6340
|
this.renderRangeHelper(range);
|
6055
6341
|
}
|
6056
6342
|
else {
|
6057
|
-
this.renderHighlight(range);
|
6343
|
+
this.renderHighlight(this.selectionRangeToSegs(range));
|
6058
6344
|
}
|
6059
6345
|
},
|
6060
6346
|
|
6061
6347
|
|
6062
6348
|
// Unrenders any visual indication of a selection
|
6063
|
-
|
6064
|
-
this.
|
6065
|
-
this.
|
6349
|
+
unrenderSelection: function() {
|
6350
|
+
this.unrenderHelper();
|
6351
|
+
this.unrenderHighlight();
|
6066
6352
|
},
|
6067
6353
|
|
6068
6354
|
|
@@ -6101,7 +6387,7 @@ var TimeGrid = Grid.extend({
|
|
6101
6387
|
|
6102
6388
|
if (colSegs.length) {
|
6103
6389
|
containerEl = $('<div class="fc-' + className + '-container"/>').appendTo(tdEl);
|
6104
|
-
dayDate = this.
|
6390
|
+
dayDate = this.colDates[col];
|
6105
6391
|
|
6106
6392
|
for (i = 0; i < colSegs.length; i++) {
|
6107
6393
|
seg = colSegs[i];
|
@@ -6150,7 +6436,7 @@ TimeGrid.mixin({
|
|
6150
6436
|
|
6151
6437
|
|
6152
6438
|
// Unrenders all currently rendered foreground event segments
|
6153
|
-
|
6439
|
+
unrenderFgSegs: function(segs) {
|
6154
6440
|
if (this.eventSkeletonEl) {
|
6155
6441
|
this.eventSkeletonEl.remove();
|
6156
6442
|
this.eventSkeletonEl = null;
|
@@ -6174,7 +6460,7 @@ TimeGrid.mixin({
|
|
6174
6460
|
|
6175
6461
|
for (col = 0; col < segCols.length; col++) { // iterate each column grouping
|
6176
6462
|
colSegs = segCols[col];
|
6177
|
-
placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array
|
6463
|
+
this.placeSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array
|
6178
6464
|
|
6179
6465
|
containerEl = $('<div class="fc-event-container"/>');
|
6180
6466
|
|
@@ -6200,6 +6486,74 @@ TimeGrid.mixin({
|
|
6200
6486
|
},
|
6201
6487
|
|
6202
6488
|
|
6489
|
+
// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
6490
|
+
// NOTE: Also reorders the given array by date!
|
6491
|
+
placeSlotSegs: function(segs) {
|
6492
|
+
var levels;
|
6493
|
+
var level0;
|
6494
|
+
var i;
|
6495
|
+
|
6496
|
+
this.sortSegs(segs); // order by date
|
6497
|
+
levels = buildSlotSegLevels(segs);
|
6498
|
+
computeForwardSlotSegs(levels);
|
6499
|
+
|
6500
|
+
if ((level0 = levels[0])) {
|
6501
|
+
|
6502
|
+
for (i = 0; i < level0.length; i++) {
|
6503
|
+
computeSlotSegPressures(level0[i]);
|
6504
|
+
}
|
6505
|
+
|
6506
|
+
for (i = 0; i < level0.length; i++) {
|
6507
|
+
this.computeSlotSegCoords(level0[i], 0, 0);
|
6508
|
+
}
|
6509
|
+
}
|
6510
|
+
},
|
6511
|
+
|
6512
|
+
|
6513
|
+
// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
6514
|
+
// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
6515
|
+
// seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
6516
|
+
//
|
6517
|
+
// The segment might be part of a "series", which means consecutive segments with the same pressure
|
6518
|
+
// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
6519
|
+
// segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
6520
|
+
// coordinate of the first segment in the series.
|
6521
|
+
computeSlotSegCoords: function(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
6522
|
+
var forwardSegs = seg.forwardSegs;
|
6523
|
+
var i;
|
6524
|
+
|
6525
|
+
if (seg.forwardCoord === undefined) { // not already computed
|
6526
|
+
|
6527
|
+
if (!forwardSegs.length) {
|
6528
|
+
|
6529
|
+
// if there are no forward segments, this segment should butt up against the edge
|
6530
|
+
seg.forwardCoord = 1;
|
6531
|
+
}
|
6532
|
+
else {
|
6533
|
+
|
6534
|
+
// sort highest pressure first
|
6535
|
+
this.sortForwardSlotSegs(forwardSegs);
|
6536
|
+
|
6537
|
+
// this segment's forwardCoord will be calculated from the backwardCoord of the
|
6538
|
+
// highest-pressure forward segment.
|
6539
|
+
this.computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
6540
|
+
seg.forwardCoord = forwardSegs[0].backwardCoord;
|
6541
|
+
}
|
6542
|
+
|
6543
|
+
// calculate the backwardCoord from the forwardCoord. consider the series
|
6544
|
+
seg.backwardCoord = seg.forwardCoord -
|
6545
|
+
(seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
6546
|
+
(seriesBackwardPressure + 1); // # of segments in the series
|
6547
|
+
|
6548
|
+
// use this segment's coordinates to computed the coordinates of the less-pressurized
|
6549
|
+
// forward segments
|
6550
|
+
for (i=0; i<forwardSegs.length; i++) {
|
6551
|
+
this.computeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);
|
6552
|
+
}
|
6553
|
+
}
|
6554
|
+
},
|
6555
|
+
|
6556
|
+
|
6203
6557
|
// Refreshes the CSS top/bottom coordinates for each segment element. Probably after a window resize/zoom.
|
6204
6558
|
// Repositions business hours segs too, so not just for events. Maybe shouldn't be here.
|
6205
6559
|
updateSegVerticals: function() {
|
@@ -6361,33 +6715,25 @@ TimeGrid.mixin({
|
|
6361
6715
|
}
|
6362
6716
|
|
6363
6717
|
return segCols;
|
6364
|
-
}
|
6365
|
-
|
6366
|
-
});
|
6367
|
-
|
6368
|
-
|
6369
|
-
// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
|
6370
|
-
// NOTE: Also reorders the given array by date!
|
6371
|
-
function placeSlotSegs(segs) {
|
6372
|
-
var levels;
|
6373
|
-
var level0;
|
6374
|
-
var i;
|
6718
|
+
},
|
6375
6719
|
|
6376
|
-
segs.sort(compareSegs); // order by date
|
6377
|
-
levels = buildSlotSegLevels(segs);
|
6378
|
-
computeForwardSlotSegs(levels);
|
6379
6720
|
|
6380
|
-
|
6721
|
+
sortForwardSlotSegs: function(forwardSegs) {
|
6722
|
+
forwardSegs.sort(proxy(this, 'compareForwardSlotSegs'));
|
6723
|
+
},
|
6381
6724
|
|
6382
|
-
for (i = 0; i < level0.length; i++) {
|
6383
|
-
computeSlotSegPressures(level0[i]);
|
6384
|
-
}
|
6385
6725
|
|
6386
|
-
|
6387
|
-
|
6388
|
-
|
6726
|
+
// A cmp function for determining which forward segment to rely on more when computing coordinates.
|
6727
|
+
compareForwardSlotSegs: function(seg1, seg2) {
|
6728
|
+
// put higher-pressure first
|
6729
|
+
return seg2.forwardPressure - seg1.forwardPressure ||
|
6730
|
+
// put segments that are closer to initial edge first (and favor ones with no coords yet)
|
6731
|
+
(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
|
6732
|
+
// do normal sorting...
|
6733
|
+
this.compareSegs(seg1, seg2);
|
6389
6734
|
}
|
6390
|
-
|
6735
|
+
|
6736
|
+
});
|
6391
6737
|
|
6392
6738
|
|
6393
6739
|
// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
|
@@ -6466,50 +6812,6 @@ function computeSlotSegPressures(seg) {
|
|
6466
6812
|
}
|
6467
6813
|
|
6468
6814
|
|
6469
|
-
// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
|
6470
|
-
// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
|
6471
|
-
// seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
|
6472
|
-
//
|
6473
|
-
// The segment might be part of a "series", which means consecutive segments with the same pressure
|
6474
|
-
// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
|
6475
|
-
// segments behind this one in the current series, and `seriesBackwardCoord` is the starting
|
6476
|
-
// coordinate of the first segment in the series.
|
6477
|
-
function computeSlotSegCoords(seg, seriesBackwardPressure, seriesBackwardCoord) {
|
6478
|
-
var forwardSegs = seg.forwardSegs;
|
6479
|
-
var i;
|
6480
|
-
|
6481
|
-
if (seg.forwardCoord === undefined) { // not already computed
|
6482
|
-
|
6483
|
-
if (!forwardSegs.length) {
|
6484
|
-
|
6485
|
-
// if there are no forward segments, this segment should butt up against the edge
|
6486
|
-
seg.forwardCoord = 1;
|
6487
|
-
}
|
6488
|
-
else {
|
6489
|
-
|
6490
|
-
// sort highest pressure first
|
6491
|
-
forwardSegs.sort(compareForwardSlotSegs);
|
6492
|
-
|
6493
|
-
// this segment's forwardCoord will be calculated from the backwardCoord of the
|
6494
|
-
// highest-pressure forward segment.
|
6495
|
-
computeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
|
6496
|
-
seg.forwardCoord = forwardSegs[0].backwardCoord;
|
6497
|
-
}
|
6498
|
-
|
6499
|
-
// calculate the backwardCoord from the forwardCoord. consider the series
|
6500
|
-
seg.backwardCoord = seg.forwardCoord -
|
6501
|
-
(seg.forwardCoord - seriesBackwardCoord) / // available width for series
|
6502
|
-
(seriesBackwardPressure + 1); // # of segments in the series
|
6503
|
-
|
6504
|
-
// use this segment's coordinates to computed the coordinates of the less-pressurized
|
6505
|
-
// forward segments
|
6506
|
-
for (i=0; i<forwardSegs.length; i++) {
|
6507
|
-
computeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);
|
6508
|
-
}
|
6509
|
-
}
|
6510
|
-
}
|
6511
|
-
|
6512
|
-
|
6513
6815
|
// Find all the segments in `otherSegs` that vertically collide with `seg`.
|
6514
6816
|
// Append into an optionally-supplied `results` array and return.
|
6515
6817
|
function computeSlotSegCollisions(seg, otherSegs, results) {
|
@@ -6530,17 +6832,6 @@ function isSlotSegCollision(seg1, seg2) {
|
|
6530
6832
|
return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
|
6531
6833
|
}
|
6532
6834
|
|
6533
|
-
|
6534
|
-
// A cmp function for determining which forward segment to rely on more when computing coordinates.
|
6535
|
-
function compareForwardSlotSegs(seg1, seg2) {
|
6536
|
-
// put higher-pressure first
|
6537
|
-
return seg2.forwardPressure - seg1.forwardPressure ||
|
6538
|
-
// put segments that are closer to initial edge first (and favor ones with no coords yet)
|
6539
|
-
(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
|
6540
|
-
// do normal sorting...
|
6541
|
-
compareSegs(seg1, seg2);
|
6542
|
-
}
|
6543
|
-
|
6544
6835
|
;;
|
6545
6836
|
|
6546
6837
|
/* An abstract class from which other views inherit from
|
@@ -6557,7 +6848,7 @@ var View = fc.View = Class.extend({
|
|
6557
6848
|
coordMap: null, // a CoordMap object for converting pixel regions to dates
|
6558
6849
|
el: null, // the view's containing element. set by Calendar
|
6559
6850
|
|
6560
|
-
|
6851
|
+
displaying: null, // a promise representing the state of rendering. null if no render requested
|
6561
6852
|
isSkeletonRendered: false,
|
6562
6853
|
isEventsRendered: false,
|
6563
6854
|
|
@@ -6572,8 +6863,11 @@ var View = fc.View = Class.extend({
|
|
6572
6863
|
intervalDuration: null,
|
6573
6864
|
intervalUnit: null, // name of largest unit being displayed, like "month" or "week"
|
6574
6865
|
|
6866
|
+
isRTL: false,
|
6575
6867
|
isSelected: false, // boolean whether a range of time is user-selected or not
|
6576
6868
|
|
6869
|
+
eventOrderSpecs: null, // criteria for ordering events when they have same date/time
|
6870
|
+
|
6577
6871
|
// subclasses can optionally use a scroll container
|
6578
6872
|
scrollerEl: null, // the element that will most likely scroll when content is too tall
|
6579
6873
|
scrollTop: null, // cached vertical scroll value
|
@@ -6601,6 +6895,9 @@ var View = fc.View = Class.extend({
|
|
6601
6895
|
this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));
|
6602
6896
|
this.initThemingProps();
|
6603
6897
|
this.initHiddenDays();
|
6898
|
+
this.isRTL = this.opt('isRTL');
|
6899
|
+
|
6900
|
+
this.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));
|
6604
6901
|
|
6605
6902
|
this.documentMousedownProxy = proxy(this, 'documentMousedown');
|
6606
6903
|
|
@@ -6790,7 +7087,7 @@ var View = fc.View = Class.extend({
|
|
6790
7087
|
|
6791
7088
|
// clean up the skeleton
|
6792
7089
|
if (this.isSkeletonRendered) {
|
6793
|
-
this.
|
7090
|
+
this.unrenderSkeleton();
|
6794
7091
|
this.isSkeletonRendered = false;
|
6795
7092
|
}
|
6796
7093
|
|
@@ -6799,62 +7096,83 @@ var View = fc.View = Class.extend({
|
|
6799
7096
|
this.el.remove();
|
6800
7097
|
|
6801
7098
|
// NOTE: don't null-out this.el in case the View was destroyed within an API callback.
|
6802
|
-
// We don't null-out the View's other jQuery element references upon destroy,
|
7099
|
+
// We don't null-out the View's other jQuery element references upon destroy,
|
7100
|
+
// so we shouldn't kill this.el either.
|
6803
7101
|
},
|
6804
7102
|
|
6805
7103
|
|
6806
7104
|
// Does everything necessary to display the view centered around the given date.
|
6807
7105
|
// Does every type of rendering EXCEPT rendering events.
|
7106
|
+
// Is asychronous and returns a promise.
|
6808
7107
|
display: function(date) {
|
7108
|
+
var _this = this;
|
6809
7109
|
var scrollState = null;
|
6810
7110
|
|
6811
|
-
if (this.
|
7111
|
+
if (this.displaying) {
|
6812
7112
|
scrollState = this.queryScroll();
|
6813
7113
|
}
|
6814
7114
|
|
6815
|
-
this.clear()
|
6816
|
-
|
6817
|
-
|
6818
|
-
|
6819
|
-
|
6820
|
-
|
6821
|
-
|
6822
|
-
|
6823
|
-
|
6824
|
-
|
6825
|
-
this.triggerRender();
|
7115
|
+
return this.clear().then(function() { // clear the content first (async)
|
7116
|
+
return (
|
7117
|
+
_this.displaying =
|
7118
|
+
$.when(_this.displayView(date)) // displayView might return a promise
|
7119
|
+
.then(function() {
|
7120
|
+
_this.forceScroll(_this.computeInitialScroll(scrollState));
|
7121
|
+
_this.triggerRender();
|
7122
|
+
})
|
7123
|
+
);
|
7124
|
+
});
|
6826
7125
|
},
|
6827
7126
|
|
6828
7127
|
|
6829
7128
|
// Does everything necessary to clear the content of the view.
|
6830
7129
|
// Clears dates and events. Does not clear the skeleton.
|
6831
|
-
|
6832
|
-
|
6833
|
-
|
6834
|
-
|
6835
|
-
|
6836
|
-
|
6837
|
-
|
6838
|
-
|
7130
|
+
// Is asychronous and returns a promise.
|
7131
|
+
clear: function() {
|
7132
|
+
var _this = this;
|
7133
|
+
var displaying = this.displaying;
|
7134
|
+
|
7135
|
+
if (displaying) { // previously displayed, or in the process of being displayed?
|
7136
|
+
return displaying.then(function() { // wait for the display to finish
|
7137
|
+
_this.displaying = null;
|
7138
|
+
_this.clearEvents();
|
7139
|
+
return _this.clearView(); // might return a promise. chain it
|
7140
|
+
});
|
7141
|
+
}
|
7142
|
+
else {
|
7143
|
+
return $.when(); // an immediately-resolved promise
|
6839
7144
|
}
|
6840
7145
|
},
|
6841
7146
|
|
6842
7147
|
|
6843
|
-
//
|
6844
|
-
|
7148
|
+
// Displays the view's non-event content, such as date-related content or anything required by events.
|
7149
|
+
// Renders the view's non-content skeleton if necessary.
|
7150
|
+
// Can be asynchronous and return a promise.
|
7151
|
+
displayView: function(date) {
|
6845
7152
|
if (!this.isSkeletonRendered) {
|
6846
7153
|
this.renderSkeleton();
|
6847
7154
|
this.isSkeletonRendered = true;
|
6848
7155
|
}
|
7156
|
+
this.setDate(date);
|
7157
|
+
if (this.render) {
|
7158
|
+
this.render(); // TODO: deprecate
|
7159
|
+
}
|
6849
7160
|
this.renderDates();
|
7161
|
+
this.updateSize();
|
7162
|
+
this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
|
6850
7163
|
},
|
6851
7164
|
|
6852
7165
|
|
6853
|
-
// Unrenders the view
|
6854
|
-
//
|
6855
|
-
|
6856
|
-
|
6857
|
-
this.
|
7166
|
+
// Unrenders the view content that was rendered in displayView.
|
7167
|
+
// Can be asynchronous and return a promise.
|
7168
|
+
clearView: function() {
|
7169
|
+
this.unselect();
|
7170
|
+
this.triggerUnrender();
|
7171
|
+
this.unrenderBusinessHours();
|
7172
|
+
this.unrenderDates();
|
7173
|
+
if (this.destroy) {
|
7174
|
+
this.destroy(); // TODO: deprecate
|
7175
|
+
}
|
6858
7176
|
},
|
6859
7177
|
|
6860
7178
|
|
@@ -6865,7 +7183,7 @@ var View = fc.View = Class.extend({
|
|
6865
7183
|
|
6866
7184
|
|
6867
7185
|
// Unrenders the basic structure of the view
|
6868
|
-
|
7186
|
+
unrenderSkeleton: function() {
|
6869
7187
|
// subclasses should implement
|
6870
7188
|
},
|
6871
7189
|
|
@@ -6878,7 +7196,7 @@ var View = fc.View = Class.extend({
|
|
6878
7196
|
|
6879
7197
|
|
6880
7198
|
// Unrenders the view's date-related content
|
6881
|
-
|
7199
|
+
unrenderDates: function() {
|
6882
7200
|
// subclasses should override
|
6883
7201
|
},
|
6884
7202
|
|
@@ -6890,7 +7208,7 @@ var View = fc.View = Class.extend({
|
|
6890
7208
|
|
6891
7209
|
|
6892
7210
|
// Unrenders previously-rendered business-hours
|
6893
|
-
|
7211
|
+
unrenderBusinessHours: function() {
|
6894
7212
|
// subclasses should implement
|
6895
7213
|
},
|
6896
7214
|
|
@@ -6902,7 +7220,7 @@ var View = fc.View = Class.extend({
|
|
6902
7220
|
|
6903
7221
|
|
6904
7222
|
// Signals that the view's content is about to be unrendered
|
6905
|
-
|
7223
|
+
triggerUnrender: function() {
|
6906
7224
|
this.trigger('viewDestroy', this, this, this.el);
|
6907
7225
|
},
|
6908
7226
|
|
@@ -6941,8 +7259,8 @@ var View = fc.View = Class.extend({
|
|
6941
7259
|
scrollState = this.queryScroll();
|
6942
7260
|
}
|
6943
7261
|
|
6944
|
-
this.updateHeight();
|
6945
|
-
this.updateWidth();
|
7262
|
+
this.updateHeight(isResize);
|
7263
|
+
this.updateWidth(isResize);
|
6946
7264
|
|
6947
7265
|
if (isResize) {
|
6948
7266
|
this.setScroll(scrollState);
|
@@ -6951,13 +7269,13 @@ var View = fc.View = Class.extend({
|
|
6951
7269
|
|
6952
7270
|
|
6953
7271
|
// Refreshes the horizontal dimensions of the calendar
|
6954
|
-
updateWidth: function() {
|
7272
|
+
updateWidth: function(isResize) {
|
6955
7273
|
// subclasses should implement
|
6956
7274
|
},
|
6957
7275
|
|
6958
7276
|
|
6959
7277
|
// Refreshes the vertical dimensions of the calendar
|
6960
|
-
updateHeight: function() {
|
7278
|
+
updateHeight: function(isResize) {
|
6961
7279
|
var calendar = this.calendar; // we poll the calendar for height information
|
6962
7280
|
|
6963
7281
|
this.setHeight(
|
@@ -7052,8 +7370,11 @@ var View = fc.View = Class.extend({
|
|
7052
7370
|
// Does everything necessary to clear the view's currently-rendered events
|
7053
7371
|
clearEvents: function() {
|
7054
7372
|
if (this.isEventsRendered) {
|
7055
|
-
this.
|
7056
|
-
this.destroyEvents
|
7373
|
+
this.triggerEventUnrender();
|
7374
|
+
if (this.destroyEvents) {
|
7375
|
+
this.destroyEvents(); // TODO: deprecate
|
7376
|
+
}
|
7377
|
+
this.unrenderEvents();
|
7057
7378
|
this.isEventsRendered = false;
|
7058
7379
|
}
|
7059
7380
|
},
|
@@ -7066,7 +7387,7 @@ var View = fc.View = Class.extend({
|
|
7066
7387
|
|
7067
7388
|
|
7068
7389
|
// Removes event elements from the view.
|
7069
|
-
|
7390
|
+
unrenderEvents: function() {
|
7070
7391
|
// subclasses should implement
|
7071
7392
|
},
|
7072
7393
|
|
@@ -7081,7 +7402,7 @@ var View = fc.View = Class.extend({
|
|
7081
7402
|
|
7082
7403
|
|
7083
7404
|
// Signals that all event elements are about to be removed
|
7084
|
-
|
7405
|
+
triggerEventUnrender: function() {
|
7085
7406
|
this.renderedEventSegEach(function(seg) {
|
7086
7407
|
this.trigger('eventDestroy', seg.event, seg.event, seg.el);
|
7087
7408
|
});
|
@@ -7230,7 +7551,7 @@ var View = fc.View = Class.extend({
|
|
7230
7551
|
|
7231
7552
|
|
7232
7553
|
// Unrenders a visual indication of an event or external-element being dragged.
|
7233
|
-
|
7554
|
+
unrenderDrag: function() {
|
7234
7555
|
// subclasses must implement
|
7235
7556
|
},
|
7236
7557
|
|
@@ -7308,6 +7629,12 @@ var View = fc.View = Class.extend({
|
|
7308
7629
|
// Called when a new selection is made. Updates internal state and triggers handlers.
|
7309
7630
|
reportSelection: function(range, ev) {
|
7310
7631
|
this.isSelected = true;
|
7632
|
+
this.triggerSelect(range, ev);
|
7633
|
+
},
|
7634
|
+
|
7635
|
+
|
7636
|
+
// Triggers handlers to 'select'
|
7637
|
+
triggerSelect: function(range, ev) {
|
7311
7638
|
this.trigger('select', null, range.start, range.end, ev);
|
7312
7639
|
},
|
7313
7640
|
|
@@ -7317,14 +7644,17 @@ var View = fc.View = Class.extend({
|
|
7317
7644
|
unselect: function(ev) {
|
7318
7645
|
if (this.isSelected) {
|
7319
7646
|
this.isSelected = false;
|
7320
|
-
this.destroySelection
|
7647
|
+
if (this.destroySelection) {
|
7648
|
+
this.destroySelection(); // TODO: deprecate
|
7649
|
+
}
|
7650
|
+
this.unrenderSelection();
|
7321
7651
|
this.trigger('unselect', null, ev);
|
7322
7652
|
}
|
7323
7653
|
},
|
7324
7654
|
|
7325
7655
|
|
7326
7656
|
// Unrenders a visual indication of selection
|
7327
|
-
|
7657
|
+
unrenderSelection: function() {
|
7328
7658
|
// subclasses should implement
|
7329
7659
|
},
|
7330
7660
|
|
@@ -7345,6 +7675,16 @@ var View = fc.View = Class.extend({
|
|
7345
7675
|
},
|
7346
7676
|
|
7347
7677
|
|
7678
|
+
/* Day Click
|
7679
|
+
------------------------------------------------------------------------------------------------------------------*/
|
7680
|
+
|
7681
|
+
|
7682
|
+
// Triggers handlers to 'dayClick'
|
7683
|
+
triggerDayClick: function(cell, dayEl, ev) {
|
7684
|
+
this.trigger('dayClick', dayEl, cell.start, ev);
|
7685
|
+
},
|
7686
|
+
|
7687
|
+
|
7348
7688
|
/* Date Utils
|
7349
7689
|
------------------------------------------------------------------------------------------------------------------*/
|
7350
7690
|
|
@@ -7443,7 +7783,7 @@ var View = fc.View = Class.extend({
|
|
7443
7783
|
|
7444
7784
|
;;
|
7445
7785
|
|
7446
|
-
var Calendar = fc.Calendar =
|
7786
|
+
var Calendar = fc.Calendar = Class.extend({
|
7447
7787
|
|
7448
7788
|
dirDefaults: null, // option defaults related to LTR or RTL
|
7449
7789
|
langDefaults: null, // option defaults related to current locale
|
@@ -7452,6 +7792,7 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7452
7792
|
viewSpecCache: null, // cache of view definitions
|
7453
7793
|
view: null, // current View object
|
7454
7794
|
header: null,
|
7795
|
+
loadingLevel: 0, // number of simultaneous loading tasks
|
7455
7796
|
|
7456
7797
|
|
7457
7798
|
// a lot of this class' OOP logic is scoped within this constructor function,
|
@@ -7459,6 +7800,11 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7459
7800
|
constructor: Calendar_constructor,
|
7460
7801
|
|
7461
7802
|
|
7803
|
+
// Subclasses can override this for initialization logic after the constructor has been called
|
7804
|
+
initialize: function() {
|
7805
|
+
},
|
7806
|
+
|
7807
|
+
|
7462
7808
|
// Initializes `this.options` and other important options-related objects
|
7463
7809
|
initOptions: function(overrides) {
|
7464
7810
|
var lang, langDefaults;
|
@@ -7485,12 +7831,12 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7485
7831
|
this.dirDefaults = dirDefaults;
|
7486
7832
|
this.langDefaults = langDefaults;
|
7487
7833
|
this.overrides = overrides;
|
7488
|
-
this.options = mergeOptions( // merge defaults and overrides. lowest to highest precedence
|
7834
|
+
this.options = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
|
7489
7835
|
Calendar.defaults, // global defaults
|
7490
7836
|
dirDefaults,
|
7491
7837
|
langDefaults,
|
7492
7838
|
overrides
|
7493
|
-
);
|
7839
|
+
]);
|
7494
7840
|
populateInstanceComputableOptions(this.options);
|
7495
7841
|
|
7496
7842
|
this.viewSpecCache = {}; // somewhat unrelated
|
@@ -7535,43 +7881,48 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7535
7881
|
// Builds an object with information on how to create a given view
|
7536
7882
|
buildViewSpec: function(requestedViewType) {
|
7537
7883
|
var viewOverrides = this.overrides.views || {};
|
7884
|
+
var specChain = []; // for the view. lowest to highest priority
|
7538
7885
|
var defaultsChain = []; // for the view. lowest to highest priority
|
7539
7886
|
var overridesChain = []; // for the view. lowest to highest priority
|
7540
7887
|
var viewType = requestedViewType;
|
7541
|
-
var
|
7542
|
-
var defaults; // for the view
|
7888
|
+
var spec; // for the view
|
7543
7889
|
var overrides; // for the view
|
7544
7890
|
var duration;
|
7545
7891
|
var unit;
|
7546
|
-
var spec;
|
7547
7892
|
|
7548
7893
|
// iterate from the specific view definition to a more general one until we hit an actual View class
|
7549
|
-
while (viewType
|
7550
|
-
|
7551
|
-
overrides = viewOverrides[viewType]
|
7552
|
-
|
7553
|
-
|
7894
|
+
while (viewType) {
|
7895
|
+
spec = fcViews[viewType];
|
7896
|
+
overrides = viewOverrides[viewType];
|
7897
|
+
viewType = null; // clear. might repopulate for another iteration
|
7898
|
+
|
7899
|
+
if (typeof spec === 'function') { // TODO: deprecate
|
7900
|
+
spec = { 'class': spec };
|
7901
|
+
}
|
7554
7902
|
|
7555
|
-
if (
|
7556
|
-
|
7557
|
-
defaultsChain.unshift(
|
7903
|
+
if (spec) {
|
7904
|
+
specChain.unshift(spec);
|
7905
|
+
defaultsChain.unshift(spec.defaults || {});
|
7906
|
+
duration = duration || spec.duration;
|
7907
|
+
viewType = viewType || spec.type;
|
7558
7908
|
}
|
7559
|
-
|
7560
|
-
|
7909
|
+
|
7910
|
+
if (overrides) {
|
7911
|
+
overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level
|
7912
|
+
duration = duration || overrides.duration;
|
7913
|
+
viewType = viewType || overrides.type;
|
7561
7914
|
}
|
7562
|
-
overridesChain.unshift(overrides);
|
7563
7915
|
}
|
7564
7916
|
|
7565
|
-
|
7566
|
-
|
7917
|
+
spec = mergeProps(specChain);
|
7918
|
+
spec.type = requestedViewType;
|
7919
|
+
if (!spec['class']) {
|
7920
|
+
return false;
|
7921
|
+
}
|
7567
7922
|
|
7568
|
-
|
7569
|
-
|
7570
|
-
|
7571
|
-
duration = null;
|
7572
|
-
}
|
7573
|
-
}
|
7574
|
-
if (duration) {
|
7923
|
+
if (duration) {
|
7924
|
+
duration = moment.duration(duration);
|
7925
|
+
if (duration.valueOf()) { // valid?
|
7575
7926
|
spec.duration = duration;
|
7576
7927
|
unit = computeIntervalUnit(duration);
|
7577
7928
|
|
@@ -7582,29 +7933,28 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7582
7933
|
overridesChain.unshift(viewOverrides[unit] || {});
|
7583
7934
|
}
|
7584
7935
|
}
|
7936
|
+
}
|
7585
7937
|
|
7586
|
-
|
7587
|
-
|
7588
|
-
spec.overrides = mergeOptions.apply(null, overridesChain);
|
7938
|
+
spec.defaults = mergeOptions(defaultsChain);
|
7939
|
+
spec.overrides = mergeOptions(overridesChain);
|
7589
7940
|
|
7590
|
-
|
7591
|
-
|
7941
|
+
this.buildViewSpecOptions(spec);
|
7942
|
+
this.buildViewSpecButtonText(spec, requestedViewType);
|
7592
7943
|
|
7593
|
-
|
7594
|
-
}
|
7944
|
+
return spec;
|
7595
7945
|
},
|
7596
7946
|
|
7597
7947
|
|
7598
7948
|
// Builds and assigns a view spec's options object from its already-assigned defaults and overrides
|
7599
7949
|
buildViewSpecOptions: function(spec) {
|
7600
|
-
spec.options = mergeOptions( // lowest to highest priority
|
7950
|
+
spec.options = mergeOptions([ // lowest to highest priority
|
7601
7951
|
Calendar.defaults, // global defaults
|
7602
7952
|
spec.defaults, // view's defaults (from ViewSubclass.defaults)
|
7603
7953
|
this.dirDefaults,
|
7604
7954
|
this.langDefaults, // locale and dir take precedence over view's defaults!
|
7605
7955
|
this.overrides, // calendar's overrides (options given to constructor)
|
7606
7956
|
spec.overrides // view's overrides (view-specific options)
|
7607
|
-
);
|
7957
|
+
]);
|
7608
7958
|
populateInstanceComputableOptions(spec.options);
|
7609
7959
|
},
|
7610
7960
|
|
@@ -7647,11 +7997,48 @@ var Calendar = fc.Calendar = fc.CalendarBase = Class.extend({
|
|
7647
7997
|
// Returns a boolean about whether the view is okay to instantiate at some point
|
7648
7998
|
isValidViewType: function(viewType) {
|
7649
7999
|
return Boolean(this.getViewSpec(viewType));
|
8000
|
+
},
|
8001
|
+
|
8002
|
+
|
8003
|
+
// Should be called when any type of async data fetching begins
|
8004
|
+
pushLoading: function() {
|
8005
|
+
if (!(this.loadingLevel++)) {
|
8006
|
+
this.trigger('loading', null, true, this.view);
|
8007
|
+
}
|
8008
|
+
},
|
8009
|
+
|
8010
|
+
|
8011
|
+
// Should be called when any type of async data fetching completes
|
8012
|
+
popLoading: function() {
|
8013
|
+
if (!(--this.loadingLevel)) {
|
8014
|
+
this.trigger('loading', null, false, this.view);
|
8015
|
+
}
|
8016
|
+
},
|
8017
|
+
|
8018
|
+
|
8019
|
+
// Given arguments to the select method in the API, returns a range
|
8020
|
+
buildSelectRange: function(start, end) {
|
8021
|
+
|
8022
|
+
start = this.moment(start);
|
8023
|
+
if (end) {
|
8024
|
+
end = this.moment(end);
|
8025
|
+
}
|
8026
|
+
else if (start.hasTime()) {
|
8027
|
+
end = start.clone().add(this.defaultTimedEventDuration);
|
8028
|
+
}
|
8029
|
+
else {
|
8030
|
+
end = start.clone().add(this.defaultAllDayEventDuration);
|
8031
|
+
}
|
8032
|
+
|
8033
|
+
return { start: start, end: end };
|
7650
8034
|
}
|
7651
8035
|
|
7652
8036
|
});
|
7653
8037
|
|
7654
8038
|
|
8039
|
+
Calendar.mixin(Emitter);
|
8040
|
+
|
8041
|
+
|
7655
8042
|
function Calendar_constructor(element, overrides) {
|
7656
8043
|
var t = this;
|
7657
8044
|
|
@@ -7930,7 +8317,7 @@ function Calendar_constructor(element, overrides) {
|
|
7930
8317
|
// It is still the "current" view, just not rendered.
|
7931
8318
|
}
|
7932
8319
|
|
7933
|
-
header.
|
8320
|
+
header.removeElement();
|
7934
8321
|
content.remove();
|
7935
8322
|
element.removeClass('fc fc-ltr fc-rtl fc-unthemed ui-widget');
|
7936
8323
|
|
@@ -7955,7 +8342,7 @@ function Calendar_constructor(element, overrides) {
|
|
7955
8342
|
function renderView(viewType) {
|
7956
8343
|
ignoreWindowResize++;
|
7957
8344
|
|
7958
|
-
// if viewType is changing,
|
8345
|
+
// if viewType is changing, remove the old view's rendering
|
7959
8346
|
if (currentView && viewType && currentView.type !== viewType) {
|
7960
8347
|
header.deactivateButton(currentView.type);
|
7961
8348
|
freezeContentHeight(); // prevent a scroll jump when view element is removed
|
@@ -7982,14 +8369,14 @@ function Calendar_constructor(element, overrides) {
|
|
7982
8369
|
|
7983
8370
|
// render or rerender the view
|
7984
8371
|
if (
|
7985
|
-
!currentView.
|
8372
|
+
!currentView.displaying ||
|
7986
8373
|
!date.isWithin(currentView.intervalStart, currentView.intervalEnd) // implicit date window change
|
7987
8374
|
) {
|
7988
8375
|
if (elementVisible()) {
|
7989
8376
|
|
7990
8377
|
freezeContentHeight();
|
7991
8378
|
currentView.display(date);
|
7992
|
-
unfreezeContentHeight();
|
8379
|
+
unfreezeContentHeight(); // immediately unfreeze regardless of whether display is async
|
7993
8380
|
|
7994
8381
|
// need to do this after View::render, so dates are calculated
|
7995
8382
|
updateHeaderTitle();
|
@@ -8157,19 +8544,9 @@ function Calendar_constructor(element, overrides) {
|
|
8157
8544
|
|
8158
8545
|
|
8159
8546
|
function select(start, end) {
|
8160
|
-
|
8161
|
-
|
8162
|
-
|
8163
|
-
end = t.moment(end);
|
8164
|
-
}
|
8165
|
-
else if (start.hasTime()) {
|
8166
|
-
end = start.clone().add(t.defaultTimedEventDuration);
|
8167
|
-
}
|
8168
|
-
else {
|
8169
|
-
end = start.clone().add(t.defaultAllDayEventDuration);
|
8170
|
-
}
|
8171
|
-
|
8172
|
-
currentView.select({ start: start, end: end }); // accepts a range
|
8547
|
+
currentView.select(
|
8548
|
+
t.buildSelectRange.apply(t, arguments)
|
8549
|
+
);
|
8173
8550
|
}
|
8174
8551
|
|
8175
8552
|
|
@@ -8295,15 +8672,18 @@ function Calendar_constructor(element, overrides) {
|
|
8295
8672
|
}
|
8296
8673
|
|
8297
8674
|
|
8298
|
-
function trigger(name, thisObj) {
|
8675
|
+
function trigger(name, thisObj) { // overrides the Emitter's trigger method :(
|
8676
|
+
var args = Array.prototype.slice.call(arguments, 2);
|
8677
|
+
|
8678
|
+
thisObj = thisObj || _element;
|
8679
|
+
this.triggerWith(name, thisObj, args); // Emitter's method
|
8680
|
+
|
8299
8681
|
if (options[name]) {
|
8300
|
-
return options[name].apply(
|
8301
|
-
thisObj || _element,
|
8302
|
-
Array.prototype.slice.call(arguments, 2)
|
8303
|
-
);
|
8682
|
+
return options[name].apply(thisObj, args);
|
8304
8683
|
}
|
8305
8684
|
}
|
8306
8685
|
|
8686
|
+
t.initialize();
|
8307
8687
|
}
|
8308
8688
|
|
8309
8689
|
;;
|
@@ -8333,6 +8713,8 @@ Calendar.defaults = {
|
|
8333
8713
|
weekNumberCalculation: 'local',
|
8334
8714
|
|
8335
8715
|
//editable: false,
|
8716
|
+
|
8717
|
+
scrollTime: '06:00:00',
|
8336
8718
|
|
8337
8719
|
// event ajax
|
8338
8720
|
lazyFetching: true,
|
@@ -8384,6 +8766,8 @@ Calendar.defaults = {
|
|
8384
8766
|
|
8385
8767
|
dropAccept: '*',
|
8386
8768
|
|
8769
|
+
eventOrder: 'title',
|
8770
|
+
|
8387
8771
|
eventLimit: false,
|
8388
8772
|
eventLimitText: 'more',
|
8389
8773
|
eventLimitClick: 'popover',
|
@@ -8475,7 +8859,7 @@ fc.lang = function(langCode, newFcOptions) {
|
|
8475
8859
|
|
8476
8860
|
// provided new options for this language? merge them in
|
8477
8861
|
if (newFcOptions) {
|
8478
|
-
fcOptions = langOptionHash[langCode] = mergeOptions(fcOptions, newFcOptions);
|
8862
|
+
fcOptions = langOptionHash[langCode] = mergeOptions([ fcOptions, newFcOptions ]);
|
8479
8863
|
}
|
8480
8864
|
|
8481
8865
|
// compute language options that weren't defined.
|
@@ -8631,7 +9015,7 @@ function Header(calendar, options) {
|
|
8631
9015
|
|
8632
9016
|
// exports
|
8633
9017
|
t.render = render;
|
8634
|
-
t.
|
9018
|
+
t.removeElement = removeElement;
|
8635
9019
|
t.updateTitle = updateTitle;
|
8636
9020
|
t.activateButton = activateButton;
|
8637
9021
|
t.deactivateButton = deactivateButton;
|
@@ -8662,8 +9046,9 @@ function Header(calendar, options) {
|
|
8662
9046
|
}
|
8663
9047
|
|
8664
9048
|
|
8665
|
-
function
|
9049
|
+
function removeElement() {
|
8666
9050
|
el.remove();
|
9051
|
+
el = $();
|
8667
9052
|
}
|
8668
9053
|
|
8669
9054
|
|
@@ -8678,6 +9063,7 @@ function Header(calendar, options) {
|
|
8678
9063
|
var groupEl;
|
8679
9064
|
|
8680
9065
|
$.each(this.split(','), function(j, buttonName) {
|
9066
|
+
var customButtonProps;
|
8681
9067
|
var viewSpec;
|
8682
9068
|
var buttonClick;
|
8683
9069
|
var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
|
@@ -8686,16 +9072,23 @@ function Header(calendar, options) {
|
|
8686
9072
|
var normalIcon;
|
8687
9073
|
var innerHtml;
|
8688
9074
|
var classes;
|
8689
|
-
var button;
|
9075
|
+
var button; // the element
|
8690
9076
|
|
8691
9077
|
if (buttonName == 'title') {
|
8692
9078
|
groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height
|
8693
9079
|
isOnlyButtons = false;
|
8694
9080
|
}
|
8695
9081
|
else {
|
8696
|
-
|
8697
|
-
|
8698
|
-
|
9082
|
+
if ((customButtonProps = (calendar.options.customButtons || {})[buttonName])) {
|
9083
|
+
buttonClick = function(ev) {
|
9084
|
+
if (customButtonProps.click) {
|
9085
|
+
customButtonProps.click.call(button[0], ev);
|
9086
|
+
}
|
9087
|
+
};
|
9088
|
+
overrideText = ''; // icons will override text
|
9089
|
+
defaultText = customButtonProps.text;
|
9090
|
+
}
|
9091
|
+
else if ((viewSpec = calendar.getViewSpec(buttonName))) {
|
8699
9092
|
buttonClick = function() {
|
8700
9093
|
calendar.changeView(buttonName);
|
8701
9094
|
};
|
@@ -8713,8 +9106,15 @@ function Header(calendar, options) {
|
|
8713
9106
|
|
8714
9107
|
if (buttonClick) {
|
8715
9108
|
|
8716
|
-
themeIcon =
|
8717
|
-
|
9109
|
+
themeIcon =
|
9110
|
+
customButtonProps ?
|
9111
|
+
customButtonProps.themeIcon :
|
9112
|
+
options.themeButtonIcons[buttonName];
|
9113
|
+
|
9114
|
+
normalIcon =
|
9115
|
+
customButtonProps ?
|
9116
|
+
customButtonProps.icon :
|
9117
|
+
options.buttonIcons[buttonName];
|
8718
9118
|
|
8719
9119
|
if (overrideText) {
|
8720
9120
|
innerHtml = htmlEscape(overrideText);
|
@@ -8740,11 +9140,11 @@ function Header(calendar, options) {
|
|
8740
9140
|
innerHtml +
|
8741
9141
|
'</button>'
|
8742
9142
|
)
|
8743
|
-
.click(function() {
|
9143
|
+
.click(function(ev) {
|
8744
9144
|
// don't process clicks for disabled buttons
|
8745
9145
|
if (!button.hasClass(tm + '-state-disabled')) {
|
8746
9146
|
|
8747
|
-
buttonClick();
|
9147
|
+
buttonClick(ev);
|
8748
9148
|
|
8749
9149
|
// after the click action, if the button becomes the "active" tab, or disabled,
|
8750
9150
|
// it should never have a hover class, so remove it now.
|
@@ -8884,8 +9284,6 @@ function EventManager(options) { // assumed to be a calendar
|
|
8884
9284
|
|
8885
9285
|
|
8886
9286
|
// imports
|
8887
|
-
var trigger = t.trigger;
|
8888
|
-
var getView = t.getView;
|
8889
9287
|
var reportEvents = t.reportEvents;
|
8890
9288
|
|
8891
9289
|
|
@@ -8895,7 +9293,6 @@ function EventManager(options) { // assumed to be a calendar
|
|
8895
9293
|
var rangeStart, rangeEnd;
|
8896
9294
|
var currentFetchID = 0;
|
8897
9295
|
var pendingSourceCnt = 0;
|
8898
|
-
var loadingLevel = 0;
|
8899
9296
|
var cache = []; // holds events that have already been expanded
|
8900
9297
|
|
8901
9298
|
|
@@ -9002,7 +9399,7 @@ function EventManager(options) { // assumed to be a calendar
|
|
9002
9399
|
var events = source.events;
|
9003
9400
|
if (events) {
|
9004
9401
|
if ($.isFunction(events)) {
|
9005
|
-
pushLoading();
|
9402
|
+
t.pushLoading();
|
9006
9403
|
events.call(
|
9007
9404
|
t, // this, the Calendar object
|
9008
9405
|
rangeStart.clone(),
|
@@ -9010,7 +9407,7 @@ function EventManager(options) { // assumed to be a calendar
|
|
9010
9407
|
options.timezone,
|
9011
9408
|
function(events) {
|
9012
9409
|
callback(events);
|
9013
|
-
popLoading();
|
9410
|
+
t.popLoading();
|
9014
9411
|
}
|
9015
9412
|
);
|
9016
9413
|
}
|
@@ -9056,7 +9453,7 @@ function EventManager(options) { // assumed to be a calendar
|
|
9056
9453
|
data[timezoneParam] = options.timezone;
|
9057
9454
|
}
|
9058
9455
|
|
9059
|
-
pushLoading();
|
9456
|
+
t.pushLoading();
|
9060
9457
|
$.ajax($.extend({}, ajaxDefaults, source, {
|
9061
9458
|
data: data,
|
9062
9459
|
success: function(events) {
|
@@ -9073,7 +9470,7 @@ function EventManager(options) { // assumed to be a calendar
|
|
9073
9470
|
},
|
9074
9471
|
complete: function() {
|
9075
9472
|
applyAll(complete, this, arguments);
|
9076
|
-
popLoading();
|
9473
|
+
t.popLoading();
|
9077
9474
|
}
|
9078
9475
|
}));
|
9079
9476
|
}else{
|
@@ -9288,25 +9685,6 @@ function EventManager(options) { // assumed to be a calendar
|
|
9288
9685
|
|
9289
9686
|
|
9290
9687
|
|
9291
|
-
/* Loading State
|
9292
|
-
-----------------------------------------------------------------------------*/
|
9293
|
-
|
9294
|
-
|
9295
|
-
function pushLoading() {
|
9296
|
-
if (!(loadingLevel++)) {
|
9297
|
-
trigger('loading', null, true, getView());
|
9298
|
-
}
|
9299
|
-
}
|
9300
|
-
|
9301
|
-
|
9302
|
-
function popLoading() {
|
9303
|
-
if (!(--loadingLevel)) {
|
9304
|
-
trigger('loading', null, false, getView());
|
9305
|
-
}
|
9306
|
-
}
|
9307
|
-
|
9308
|
-
|
9309
|
-
|
9310
9688
|
/* Event Normalization
|
9311
9689
|
-----------------------------------------------------------------------------*/
|
9312
9690
|
|
@@ -9991,7 +10369,7 @@ function backupEventDates(event) {
|
|
9991
10369
|
// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
|
9992
10370
|
// It is responsible for managing width/height.
|
9993
10371
|
|
9994
|
-
var BasicView =
|
10372
|
+
var BasicView = View.extend({
|
9995
10373
|
|
9996
10374
|
dayGrid: null, // the main subcomponent that does most of the heavy lifting
|
9997
10375
|
|
@@ -10039,7 +10417,7 @@ var BasicView = fcViews.basic = View.extend({
|
|
10039
10417
|
|
10040
10418
|
|
10041
10419
|
// Renders the view into `this.el`, which should already be assigned
|
10042
|
-
|
10420
|
+
renderDates: function() {
|
10043
10421
|
|
10044
10422
|
this.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible
|
10045
10423
|
this.weekNumbersVisible = this.opt('weekNumbers');
|
@@ -10059,8 +10437,8 @@ var BasicView = fcViews.basic = View.extend({
|
|
10059
10437
|
|
10060
10438
|
// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
|
10061
10439
|
// always completely kill the dayGrid's rendering.
|
10062
|
-
|
10063
|
-
this.dayGrid.
|
10440
|
+
unrenderDates: function() {
|
10441
|
+
this.dayGrid.unrenderDates();
|
10064
10442
|
this.dayGrid.removeElement();
|
10065
10443
|
},
|
10066
10444
|
|
@@ -10203,7 +10581,7 @@ var BasicView = fcViews.basic = View.extend({
|
|
10203
10581
|
unsetScroller(this.scrollerEl);
|
10204
10582
|
uncompensateScroll(this.headRowEl);
|
10205
10583
|
|
10206
|
-
this.dayGrid.
|
10584
|
+
this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
|
10207
10585
|
|
10208
10586
|
// is the event limit a constant level number?
|
10209
10587
|
if (eventLimit && typeof eventLimit === 'number') {
|
@@ -10259,8 +10637,8 @@ var BasicView = fcViews.basic = View.extend({
|
|
10259
10637
|
|
10260
10638
|
|
10261
10639
|
// Unrenders all event elements and clears internal segment data
|
10262
|
-
|
10263
|
-
this.dayGrid.
|
10640
|
+
unrenderEvents: function() {
|
10641
|
+
this.dayGrid.unrenderEvents();
|
10264
10642
|
|
10265
10643
|
// we DON'T need to call updateHeight() because:
|
10266
10644
|
// A) a renderEvents() call always happens after this, which will eventually call updateHeight()
|
@@ -10278,8 +10656,8 @@ var BasicView = fcViews.basic = View.extend({
|
|
10278
10656
|
},
|
10279
10657
|
|
10280
10658
|
|
10281
|
-
|
10282
|
-
this.dayGrid.
|
10659
|
+
unrenderDrag: function() {
|
10660
|
+
this.dayGrid.unrenderDrag();
|
10283
10661
|
},
|
10284
10662
|
|
10285
10663
|
|
@@ -10294,8 +10672,8 @@ var BasicView = fcViews.basic = View.extend({
|
|
10294
10672
|
|
10295
10673
|
|
10296
10674
|
// Unrenders a visual indications of a selection
|
10297
|
-
|
10298
|
-
this.dayGrid.
|
10675
|
+
unrenderSelection: function() {
|
10676
|
+
this.dayGrid.unrenderSelection();
|
10299
10677
|
}
|
10300
10678
|
|
10301
10679
|
});
|
@@ -10305,7 +10683,7 @@ var BasicView = fcViews.basic = View.extend({
|
|
10305
10683
|
/* A month view with day cells running in rows (one-per-week) and columns
|
10306
10684
|
----------------------------------------------------------------------------------------------------------------------*/
|
10307
10685
|
|
10308
|
-
var MonthView =
|
10686
|
+
var MonthView = BasicView.extend({
|
10309
10687
|
|
10310
10688
|
// Produces information about what range to display
|
10311
10689
|
computeRange: function(date) {
|
@@ -10347,28 +10725,28 @@ var MonthView = fcViews.month = BasicView.extend({
|
|
10347
10725
|
|
10348
10726
|
});
|
10349
10727
|
|
10350
|
-
|
10728
|
+
;;
|
10351
10729
|
|
10352
|
-
|
10353
|
-
|
10730
|
+
fcViews.basic = {
|
10731
|
+
'class': BasicView
|
10354
10732
|
};
|
10355
|
-
;;
|
10356
10733
|
|
10357
|
-
|
10358
|
-
|
10734
|
+
fcViews.basicDay = {
|
10735
|
+
type: 'basic',
|
10736
|
+
duration: { days: 1 }
|
10737
|
+
};
|
10359
10738
|
|
10360
10739
|
fcViews.basicWeek = {
|
10361
10740
|
type: 'basic',
|
10362
10741
|
duration: { weeks: 1 }
|
10363
10742
|
};
|
10364
|
-
;;
|
10365
10743
|
|
10366
|
-
|
10367
|
-
|
10368
|
-
|
10369
|
-
|
10370
|
-
|
10371
|
-
|
10744
|
+
fcViews.month = {
|
10745
|
+
'class': MonthView,
|
10746
|
+
duration: { months: 1 }, // important for prev/next
|
10747
|
+
defaults: {
|
10748
|
+
fixedWeekCount: true
|
10749
|
+
}
|
10372
10750
|
};
|
10373
10751
|
;;
|
10374
10752
|
|
@@ -10377,19 +10755,7 @@ fcViews.basicDay = {
|
|
10377
10755
|
// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
|
10378
10756
|
// Responsible for managing width/height.
|
10379
10757
|
|
10380
|
-
var
|
10381
|
-
allDaySlot: true,
|
10382
|
-
allDayText: 'all-day',
|
10383
|
-
scrollTime: '06:00:00',
|
10384
|
-
slotDuration: '00:30:00',
|
10385
|
-
minTime: '00:00:00',
|
10386
|
-
maxTime: '24:00:00',
|
10387
|
-
slotEventOverlap: true // a bad name. confused with overlap/constraint system
|
10388
|
-
};
|
10389
|
-
|
10390
|
-
var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
|
10391
|
-
|
10392
|
-
var AgendaView = fcViews.agenda = View.extend({
|
10758
|
+
var AgendaView = View.extend({
|
10393
10759
|
|
10394
10760
|
timeGrid: null, // the main time-grid subcomponent of this view
|
10395
10761
|
dayGrid: null, // the "all-day" subcomponent. if all-day is turned off, this will be null
|
@@ -10437,7 +10803,7 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10437
10803
|
|
10438
10804
|
|
10439
10805
|
// Renders the view into `this.el`, which has already been assigned
|
10440
|
-
|
10806
|
+
renderDates: function() {
|
10441
10807
|
|
10442
10808
|
this.el.addClass('fc-agenda-view').html(this.renderHtml());
|
10443
10809
|
|
@@ -10466,12 +10832,12 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10466
10832
|
|
10467
10833
|
// Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
|
10468
10834
|
// always completely kill each grid's rendering.
|
10469
|
-
|
10470
|
-
this.timeGrid.
|
10835
|
+
unrenderDates: function() {
|
10836
|
+
this.timeGrid.unrenderDates();
|
10471
10837
|
this.timeGrid.removeElement();
|
10472
10838
|
|
10473
10839
|
if (this.dayGrid) {
|
10474
|
-
this.dayGrid.
|
10840
|
+
this.dayGrid.unrenderDates();
|
10475
10841
|
this.dayGrid.removeElement();
|
10476
10842
|
}
|
10477
10843
|
},
|
@@ -10610,7 +10976,7 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10610
10976
|
|
10611
10977
|
// limit number of events in the all-day area
|
10612
10978
|
if (this.dayGrid) {
|
10613
|
-
this.dayGrid.
|
10979
|
+
this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
|
10614
10980
|
|
10615
10981
|
eventLimit = this.opt('eventLimit');
|
10616
10982
|
if (eventLimit && typeof eventLimit !== 'number') {
|
@@ -10701,12 +11067,12 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10701
11067
|
|
10702
11068
|
|
10703
11069
|
// Unrenders all event elements and clears internal segment data
|
10704
|
-
|
11070
|
+
unrenderEvents: function() {
|
10705
11071
|
|
10706
|
-
//
|
10707
|
-
this.timeGrid.
|
11072
|
+
// unrender the events in the subcomponents
|
11073
|
+
this.timeGrid.unrenderEvents();
|
10708
11074
|
if (this.dayGrid) {
|
10709
|
-
this.dayGrid.
|
11075
|
+
this.dayGrid.unrenderEvents();
|
10710
11076
|
}
|
10711
11077
|
|
10712
11078
|
// we DON'T need to call updateHeight() because:
|
@@ -10730,10 +11096,10 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10730
11096
|
},
|
10731
11097
|
|
10732
11098
|
|
10733
|
-
|
10734
|
-
this.timeGrid.
|
11099
|
+
unrenderDrag: function() {
|
11100
|
+
this.timeGrid.unrenderDrag();
|
10735
11101
|
if (this.dayGrid) {
|
10736
|
-
this.dayGrid.
|
11102
|
+
this.dayGrid.unrenderDrag();
|
10737
11103
|
}
|
10738
11104
|
},
|
10739
11105
|
|
@@ -10754,35 +11120,50 @@ var AgendaView = fcViews.agenda = View.extend({
|
|
10754
11120
|
|
10755
11121
|
|
10756
11122
|
// Unrenders a visual indications of a selection
|
10757
|
-
|
10758
|
-
this.timeGrid.
|
11123
|
+
unrenderSelection: function() {
|
11124
|
+
this.timeGrid.unrenderSelection();
|
10759
11125
|
if (this.dayGrid) {
|
10760
|
-
this.dayGrid.
|
11126
|
+
this.dayGrid.unrenderSelection();
|
10761
11127
|
}
|
10762
11128
|
}
|
10763
11129
|
|
10764
11130
|
});
|
10765
11131
|
|
10766
|
-
AgendaView.defaults = AGENDA_DEFAULTS;
|
10767
|
-
|
10768
11132
|
;;
|
10769
11133
|
|
10770
|
-
|
10771
|
-
----------------------------------------------------------------------------------------------------------------------*/
|
11134
|
+
var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
|
10772
11135
|
|
10773
|
-
|
10774
|
-
|
10775
|
-
|
10776
|
-
}
|
10777
|
-
|
11136
|
+
// potential nice values for the slot-duration and interval-duration
|
11137
|
+
// from largest to smallest
|
11138
|
+
var AGENDA_STOCK_SUB_DURATIONS = [
|
11139
|
+
{ hours: 1 },
|
11140
|
+
{ minutes: 30 },
|
11141
|
+
{ minutes: 15 },
|
11142
|
+
{ seconds: 30 },
|
11143
|
+
{ seconds: 15 }
|
11144
|
+
];
|
10778
11145
|
|
10779
|
-
|
10780
|
-
|
11146
|
+
fcViews.agenda = {
|
11147
|
+
'class': AgendaView,
|
11148
|
+
defaults: {
|
11149
|
+
allDaySlot: true,
|
11150
|
+
allDayText: 'all-day',
|
11151
|
+
slotDuration: '00:30:00',
|
11152
|
+
minTime: '00:00:00',
|
11153
|
+
maxTime: '24:00:00',
|
11154
|
+
slotEventOverlap: true // a bad name. confused with overlap/constraint system
|
11155
|
+
}
|
11156
|
+
};
|
10781
11157
|
|
10782
11158
|
fcViews.agendaDay = {
|
10783
11159
|
type: 'agenda',
|
10784
11160
|
duration: { days: 1 }
|
10785
11161
|
};
|
11162
|
+
|
11163
|
+
fcViews.agendaWeek = {
|
11164
|
+
type: 'agenda',
|
11165
|
+
duration: { weeks: 1 }
|
11166
|
+
};
|
10786
11167
|
;;
|
10787
11168
|
|
10788
11169
|
return fc; // export for Node/CommonJS
|