fullcalendar-rails 2.4.0.0 → 2.4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|