Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
(function ($) {
Drupal.behaviors.dateSelect = {};
Drupal.behaviors.dateSelect.attach = function (context, settings) {
var $widget = $('.form-type-date-select').parents('fieldset').once('date');
var i;
for (i = 0; i < $widget.length; i++) {
new Drupal.date.EndDateHandler($widget[i]);
}
};
Drupal.date = Drupal.date || {};
/**
* Constructor for the EndDateHandler object.
*
* The EndDateHandler is responsible for synchronizing a date select widget's
* end date with its start date. This behavior lasts until the user
* interacts with the end date widget.
*
* @param widget
* The fieldset DOM element containing the from and to dates.
*/
Drupal.date.EndDateHandler = function (widget) {
this.$widget = $(widget);
this.$start = this.$widget.find('.form-type-date-select[class$=value]');
this.$end = this.$widget.find('.form-type-date-select[class$=value2]');
if (this.$end.length == 0) {
return;
}
this.initializeSelects();
// Only act on date fields where the end date is completely blank or already
// the same as the start date. Otherwise, we do not want to override whatever
// the default value was.
if (this.endDateIsBlank() || this.endDateIsSame()) {
this.bindClickHandlers();
// Start out with identical start and end dates.
this.syncEndDate();
}
};
/**
* Store all the select dropdowns in an array on the object, for later use.
*/
Drupal.date.EndDateHandler.prototype.initializeSelects = function () {
var $starts = this.$start.find('select');
var $end, $start, endId, i, id;
this.selects = {};
for (i = 0; i < $starts.length; i++) {
$start = $($starts[i]);
id = $start.attr('id');
endId = id.replace('-value-', '-value2-');
$end = $('#' + endId);
this.selects[id] = {
'id': id,
'start': $start,
'end': $end
};
}
};
/**
* Returns true if all dropdowns in the end date widget are blank.
*/
Drupal.date.EndDateHandler.prototype.endDateIsBlank = function () {
var id;
for (id in this.selects) {
if (this.selects.hasOwnProperty(id)) {
if (this.selects[id].end.val() != '') {
return false;
}
}
}
return true;
};
/**
* Returns true if the end date widget has the same value as the start date.
*/
Drupal.date.EndDateHandler.prototype.endDateIsSame = function () {
var id;
for (id in this.selects) {
if (this.selects.hasOwnProperty(id)) {
if (this.selects[id].end.val() != this.selects[id].start.val()) {
return false;
}
}
}
return true;
};
/**
* Add a click handler to each of the start date's select dropdowns.
*/
Drupal.date.EndDateHandler.prototype.bindClickHandlers = function () {
var id;
for (id in this.selects) {
if (this.selects.hasOwnProperty(id)) {
this.selects[id].start.bind('click.endDateHandler', this.startClickHandler.bind(this));
this.selects[id].end.bind('focus', this.endFocusHandler.bind(this));
}
}
};
/**
* Click event handler for each of the start date's select dropdowns.
*/
Drupal.date.EndDateHandler.prototype.startClickHandler = function (event) {
this.syncEndDate();
};
/**
* Focus event handler for each of the end date's select dropdowns.
*/
Drupal.date.EndDateHandler.prototype.endFocusHandler = function (event) {
var id;
for (id in this.selects) {
if (this.selects.hasOwnProperty(id)) {
this.selects[id].start.unbind('click.endDateHandler');
}
}
$(event.target).unbind('focus', this.endFocusHandler);
};
Drupal.date.EndDateHandler.prototype.syncEndDate = function () {
var id;
for (id in this.selects) {
if (this.selects.hasOwnProperty(id)) {
this.selects[id].end.val(this.selects[id].start.val());
}
}
};
}(jQuery));
/**
* Function.prototype.bind polyfill for older browsers.
* https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
*/
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") // closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable");
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}