1 |
efrain |
1 |
YUI.add('calendarnavigator', function (Y, NAME) {
|
|
|
2 |
|
|
|
3 |
/**
|
|
|
4 |
* Provides a plugin which adds navigation controls to Calendar.
|
|
|
5 |
*
|
|
|
6 |
* @module calendarnavigator
|
|
|
7 |
*/
|
|
|
8 |
var CONTENT_BOX = "contentBox",
|
|
|
9 |
HOST = "host",
|
|
|
10 |
getCN = Y.ClassNameManager.getClassName,
|
|
|
11 |
substitute = Y.Lang.sub,
|
|
|
12 |
node = Y.Node,
|
|
|
13 |
create = node.create,
|
|
|
14 |
CALENDAR = 'calendar',
|
|
|
15 |
CALENDARNAV = 'calendarnav',
|
|
|
16 |
CAL_HD = getCN(CALENDAR, 'header'),
|
|
|
17 |
CAL_PREV_M = getCN(CALENDARNAV, 'prevmonth'),
|
|
|
18 |
CAL_NEXT_M = getCN(CALENDARNAV, 'nextmonth'),
|
|
|
19 |
CAL_DIS_M = getCN(CALENDARNAV, 'month-disabled'),
|
|
|
20 |
ydate = Y.DataType.Date;
|
|
|
21 |
/**
|
|
|
22 |
* A plugin class which adds navigation controls to Calendar.
|
|
|
23 |
*
|
|
|
24 |
* @class CalendarNavigator
|
|
|
25 |
* @extends Plugin.Base
|
|
|
26 |
* @namespace Plugin
|
|
|
27 |
*/
|
|
|
28 |
function CalendarNavigator() {
|
|
|
29 |
CalendarNavigator.superclass.constructor.apply(this, arguments);
|
|
|
30 |
}
|
|
|
31 |
|
|
|
32 |
/**
|
|
|
33 |
* The namespace for the plugin. This will be the property on the widget, which will
|
|
|
34 |
* reference the plugin instance, when it's plugged in.
|
|
|
35 |
*
|
|
|
36 |
* @property NS
|
|
|
37 |
* @static
|
|
|
38 |
* @type String
|
|
|
39 |
* @default "navigator"
|
|
|
40 |
*/
|
|
|
41 |
CalendarNavigator.NS = "navigator";
|
|
|
42 |
|
|
|
43 |
/**
|
|
|
44 |
* The NAME of the CalendarNavigator class. Used to prefix events generated
|
|
|
45 |
* by the plugin class.
|
|
|
46 |
*
|
|
|
47 |
* @property NAME
|
|
|
48 |
* @static
|
|
|
49 |
* @type String
|
|
|
50 |
* @default "pluginCalendarNavigator"
|
|
|
51 |
*/
|
|
|
52 |
CalendarNavigator.NAME = "pluginCalendarNavigator";
|
|
|
53 |
|
|
|
54 |
|
|
|
55 |
/**
|
|
|
56 |
* Static property used to define the default attribute
|
|
|
57 |
* configuration for the plugin.
|
|
|
58 |
*
|
|
|
59 |
* @property ATTRS
|
|
|
60 |
* @type Object
|
|
|
61 |
* @static
|
|
|
62 |
*/
|
|
|
63 |
CalendarNavigator.ATTRS = {
|
|
|
64 |
|
|
|
65 |
/**
|
|
|
66 |
* The number of months to shift by when the control arrows are clicked.
|
|
|
67 |
*
|
|
|
68 |
* @attribute shiftByMonths
|
|
|
69 |
* @type Number
|
|
|
70 |
* @default 1 (months)
|
|
|
71 |
*/
|
|
|
72 |
shiftByMonths : {
|
|
|
73 |
value: 1
|
|
|
74 |
}
|
|
|
75 |
};
|
|
|
76 |
|
|
|
77 |
/**
|
|
|
78 |
* The CSS classnames for the calendar navigator controls.
|
|
|
79 |
* @property CALENDARNAV_STRINGS
|
|
|
80 |
* @type Object
|
|
|
81 |
* @readOnly
|
|
|
82 |
* @protected
|
|
|
83 |
* @static
|
|
|
84 |
*/
|
|
|
85 |
CalendarNavigator.CALENDARNAV_STRINGS = {
|
|
|
86 |
prev_month_class: CAL_PREV_M,
|
|
|
87 |
next_month_class: CAL_NEXT_M
|
|
|
88 |
};
|
|
|
89 |
|
|
|
90 |
/**
|
|
|
91 |
* The template for the calendar navigator previous month control.
|
|
|
92 |
* @property PREV_MONTH_CONTROL_TEMPLATE
|
|
|
93 |
* @type String
|
|
|
94 |
* @protected
|
|
|
95 |
* @static
|
|
|
96 |
*/
|
|
|
97 |
CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {prev_month_class}" role="button" aria-label="{prev_month_arialabel}" ' +
|
|
|
98 |
'tabindex="{control_tabindex}" />';
|
|
|
99 |
/**
|
|
|
100 |
* The template for the calendar navigator next month control.
|
|
|
101 |
* @property NEXT_MONTH_CONTROL_TEMPLATE
|
|
|
102 |
* @type String
|
|
|
103 |
* @readOnly
|
|
|
104 |
* @protected
|
|
|
105 |
* @static
|
|
|
106 |
*/
|
|
|
107 |
CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {next_month_class}" role="button" aria-label="{next_month_arialabel}" ' +
|
|
|
108 |
'tabindex="{control_tabindex}" />';
|
|
|
109 |
|
|
|
110 |
|
|
|
111 |
Y.extend(CalendarNavigator, Y.Plugin.Base, {
|
|
|
112 |
|
|
|
113 |
_eventAttachments : {},
|
|
|
114 |
_controls: {},
|
|
|
115 |
|
|
|
116 |
/**
|
|
|
117 |
* The initializer lifecycle implementation. Modifies the host widget's
|
|
|
118 |
* render to add navigation controls.
|
|
|
119 |
*
|
|
|
120 |
* @method initializer
|
|
|
121 |
*/
|
|
|
122 |
initializer : function() {
|
|
|
123 |
|
|
|
124 |
// After the host has rendered its UI, place the navigation cotnrols
|
|
|
125 |
this._controls = {};
|
|
|
126 |
this._eventAttachments = {};
|
|
|
127 |
|
|
|
128 |
this.afterHostMethod("renderUI", this._initNavigationControls);
|
|
|
129 |
},
|
|
|
130 |
|
|
|
131 |
/**
|
|
|
132 |
* The initializer destructor implementation. Responsible for destroying the initialized
|
|
|
133 |
* control mechanisms.
|
|
|
134 |
*
|
|
|
135 |
* @method destructor
|
|
|
136 |
*/
|
|
|
137 |
destructor : function() {
|
|
|
138 |
|
|
|
139 |
},
|
|
|
140 |
|
|
|
141 |
/**
|
|
|
142 |
* Private utility method that focuses on a navigation button when it is clicked
|
|
|
143 |
* or pressed with a keyboard.
|
|
|
144 |
*
|
|
|
145 |
* @method _focusNavigation
|
|
|
146 |
* @param {Event} ev Click or keydown event from the controls
|
|
|
147 |
* @protected
|
|
|
148 |
*/
|
|
|
149 |
_focusNavigation : function (ev) {
|
|
|
150 |
ev.currentTarget.focus();
|
|
|
151 |
},
|
|
|
152 |
|
|
|
153 |
/**
|
|
|
154 |
* Private utility method that subtracts months from the host calendar date
|
|
|
155 |
* based on the control click and the shiftByMonths property.
|
|
|
156 |
*
|
|
|
157 |
* @method _subtractMonths
|
|
|
158 |
* @param {Event} ev Click event from the controls
|
|
|
159 |
* @protected
|
|
|
160 |
*/
|
|
|
161 |
_subtractMonths : function (ev) {
|
|
|
162 |
if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
|
|
|
163 |
var host = this.get(HOST),
|
|
|
164 |
oldDate = host.get("date");
|
|
|
165 |
host.set("date", ydate.addMonths(oldDate, -1*this.get("shiftByMonths")));
|
|
|
166 |
ev.preventDefault();
|
|
|
167 |
}
|
|
|
168 |
},
|
|
|
169 |
|
|
|
170 |
/**
|
|
|
171 |
* Private utility method that adds months to the host calendar date
|
|
|
172 |
* based on the control click and the shiftByMonths property.
|
|
|
173 |
*
|
|
|
174 |
* @method _addMonths
|
|
|
175 |
* @param {Event} ev Click event from the controls
|
|
|
176 |
* @protected
|
|
|
177 |
*/
|
|
|
178 |
_addMonths : function (ev) {
|
|
|
179 |
if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
|
|
|
180 |
var host = this.get(HOST),
|
|
|
181 |
oldDate = host.get("date");
|
|
|
182 |
host.set("date", ydate.addMonths(oldDate, this.get("shiftByMonths")));
|
|
|
183 |
ev.preventDefault();
|
|
|
184 |
}
|
|
|
185 |
},
|
|
|
186 |
|
|
|
187 |
|
|
|
188 |
_updateControlState : function () {
|
|
|
189 |
|
|
|
190 |
var host = this.get(HOST),
|
|
|
191 |
startDate = host.get('date'),
|
|
|
192 |
endDate = ydate.addMonths(startDate, host._paneNumber - 1),
|
|
|
193 |
minDate = host._normalizeDate(host.get("minimumDate")),
|
|
|
194 |
maxDate = host._normalizeDate(host.get("maximumDate"));
|
|
|
195 |
|
|
|
196 |
if (ydate.areEqual(minDate, startDate)) {
|
|
|
197 |
if (this._eventAttachments.prevMonth) {
|
|
|
198 |
this._eventAttachments.prevMonth.detach();
|
|
|
199 |
this._eventAttachments.prevMonth = false;
|
|
|
200 |
}
|
|
|
201 |
|
|
|
202 |
if (!this._controls.prevMonth.hasClass(CAL_DIS_M)) {
|
|
|
203 |
this._controls.prevMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
|
|
|
204 |
}
|
|
|
205 |
}
|
|
|
206 |
else {
|
|
|
207 |
if (!this._eventAttachments.prevMonth) {
|
|
|
208 |
this._eventAttachments.prevMonth = this._controls.prevMonth.on(["click", "keydown"], this._subtractMonths, this);
|
|
|
209 |
}
|
|
|
210 |
if (this._controls.prevMonth.hasClass(CAL_DIS_M)) {
|
|
|
211 |
this._controls.prevMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
|
|
|
212 |
}
|
|
|
213 |
}
|
|
|
214 |
|
|
|
215 |
if (ydate.areEqual(maxDate, endDate)) {
|
|
|
216 |
if (this._eventAttachments.nextMonth) {
|
|
|
217 |
this._eventAttachments.nextMonth.detach();
|
|
|
218 |
this._eventAttachments.nextMonth = false;
|
|
|
219 |
}
|
|
|
220 |
|
|
|
221 |
if (!this._controls.nextMonth.hasClass(CAL_DIS_M)) {
|
|
|
222 |
this._controls.nextMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
|
|
|
223 |
}
|
|
|
224 |
}
|
|
|
225 |
else {
|
|
|
226 |
if (!this._eventAttachments.nextMonth) {
|
|
|
227 |
this._eventAttachments.nextMonth = this._controls.nextMonth.on(["click", "keydown"], this._addMonths, this);
|
|
|
228 |
}
|
|
|
229 |
if (this._controls.nextMonth.hasClass(CAL_DIS_M)) {
|
|
|
230 |
this._controls.nextMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
|
|
|
231 |
}
|
|
|
232 |
}
|
|
|
233 |
|
|
|
234 |
this._controls.prevMonth.on(["click", "keydown"], this._focusNavigation, this);
|
|
|
235 |
this._controls.nextMonth.on(["click", "keydown"], this._focusNavigation, this);
|
|
|
236 |
},
|
|
|
237 |
|
|
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
|
241 |
/**
|
|
|
242 |
* Private render assist method that renders the previous month control
|
|
|
243 |
*
|
|
|
244 |
* @method _renderPrevControls
|
|
|
245 |
* @private
|
|
|
246 |
*/
|
|
|
247 |
_renderPrevControls : function () {
|
|
|
248 |
var prevControlNode = create(substitute (CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE,
|
|
|
249 |
CalendarNavigator.CALENDARNAV_STRINGS));
|
|
|
250 |
prevControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);
|
|
|
251 |
|
|
|
252 |
return prevControlNode;
|
|
|
253 |
},
|
|
|
254 |
|
|
|
255 |
/**
|
|
|
256 |
* Private render assist method that renders the next month control
|
|
|
257 |
*
|
|
|
258 |
* @method _renderNextControls
|
|
|
259 |
* @private
|
|
|
260 |
*/
|
|
|
261 |
_renderNextControls : function () {
|
|
|
262 |
var nextControlNode = create(substitute (CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE,
|
|
|
263 |
CalendarNavigator.CALENDARNAV_STRINGS));
|
|
|
264 |
nextControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);
|
|
|
265 |
|
|
|
266 |
return nextControlNode;
|
|
|
267 |
},
|
|
|
268 |
|
|
|
269 |
/**
|
|
|
270 |
* Protected render assist method that initialized and renders the navigation controls.
|
|
|
271 |
* @method _initNavigationControls
|
|
|
272 |
* @protected
|
|
|
273 |
*/
|
|
|
274 |
_initNavigationControls : function() {
|
|
|
275 |
var host = this.get(HOST),
|
|
|
276 |
headerCell = host.get(CONTENT_BOX).one("." + CAL_HD);
|
|
|
277 |
|
|
|
278 |
CalendarNavigator.CALENDARNAV_STRINGS.control_tabindex = host.get("tabIndex");
|
|
|
279 |
CalendarNavigator.CALENDARNAV_STRINGS.prev_month_arialabel = "Go to previous month";
|
|
|
280 |
CalendarNavigator.CALENDARNAV_STRINGS.next_month_arialabel = "Go to next month";
|
|
|
281 |
|
|
|
282 |
this._controls.prevMonth = this._renderPrevControls();
|
|
|
283 |
this._controls.nextMonth = this._renderNextControls();
|
|
|
284 |
|
|
|
285 |
this._updateControlState();
|
|
|
286 |
|
|
|
287 |
host.after(["dateChange", "minimumDateChange", "maximumDateChange"], this._updateControlState, this);
|
|
|
288 |
|
|
|
289 |
headerCell.prepend(this._controls.prevMonth);
|
|
|
290 |
headerCell.append(this._controls.nextMonth);
|
|
|
291 |
}
|
|
|
292 |
});
|
|
|
293 |
|
|
|
294 |
Y.namespace("Plugin").CalendarNavigator = CalendarNavigator;
|
|
|
295 |
|
|
|
296 |
|
|
|
297 |
}, '3.18.1', {"requires": ["plugin", "classnamemanager", "datatype-date", "node"], "skinnable": true});
|