summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI-extensions/widgets/DatePicker.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI-extensions/widgets/DatePicker.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI-extensions/widgets/DatePicker.js344
1 files changed, 344 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/widgets/DatePicker.js b/frontend/beta/js/YUI-extensions/widgets/DatePicker.js
new file mode 100644
index 0000000..eb1e06f
--- a/dev/null
+++ b/frontend/beta/js/YUI-extensions/widgets/DatePicker.js
@@ -0,0 +1,344 @@
1YAHOO.ext.DatePicker = function(id, parentElement){
2 this.id = id;
3 this.selectedDate = new Date();
4 this.visibleDate = new Date();
5 this.element = null;
6 this.shadow = null;
7 this.callback = null;
8 this.buildControl(parentElement || document.body);
9 this.mouseDownHandler = YAHOO.ext.EventManager.wrap(this.handleMouseDown, this, true);
10 this.keyDownHandler = YAHOO.ext.EventManager.wrap(this.handleKeyDown, this, true);
11 this.wheelHandler = YAHOO.ext.EventManager.wrap(this.handleMouseWheel, this, true);
12};
13
14YAHOO.ext.DatePicker.prototype = {
15 show : function(x, y, value, callback){
16 this.hide();
17 this.selectedDate = value;
18 this.visibleDate = value;
19 this.callback = callback;
20 this.refresh();
21 this.element.show();
22 this.element.setXY(this.constrainToViewport ? this.constrainXY(x, y) : [x, y]);
23 this.shadow.show();
24 this.shadow.setRegion(this.element.getRegion());
25 this.element.dom.tabIndex = 1;
26 this.element.focus();
27 YAHOO.util.Event.on(document, "mousedown", this.mouseDownHandler);
28 YAHOO.util.Event.on(document, "keydown", this.keyDownHandler);
29 YAHOO.util.Event.on(document, "mousewheel", this.wheelHandler);
30 YAHOO.util.Event.on(document, "DOMMouseScroll", this.wheelHandler);
31 },
32
33 constrainXY : function(x, y){
34 var w = YAHOO.util.Dom.getViewportWidth();
35 var h = YAHOO.util.Dom.getViewportHeight();
36 var size = this.element.getSize();
37 return [
38 Math.min(w-size.width, x),
39 Math.min(h-size.height, y)
40 ];
41 },
42
43 hide : function(){
44 this.shadow.hide();
45 this.element.hide();
46 YAHOO.util.Event.removeListener(document, "mousedown", this.mouseDownHandler);
47 YAHOO.util.Event.removeListener(document, "keydown", this.keyDownHandler);
48 YAHOO.util.Event.removeListener(document, "mousewheel", this.wheelHandler);
49 YAHOO.util.Event.removeListener(document, "DOMMouseScroll", this.wheelHandler);
50 },
51
52 setSelectedDate : function(date){
53 this.selectedDate = date;
54 },
55
56 getSelectedDate : function(){
57 return this.selectedDate;
58 },
59
60 showPrevMonth : function(){
61 this.visibleDate = this.getPrevMonth(this.visibleDate);
62 this.refresh();
63 },
64
65 showNextMonth : function(){
66 this.visibleDate = this.getNextMonth(this.visibleDate);
67 this.refresh();
68 },
69
70 showPrevYear : function(){
71 var d = this.visibleDate;
72 this.visibleDate = new Date(d.getFullYear()-1, d.getMonth(), d.getDate());
73 this.refresh();
74 },
75
76 showNextYear : function(){
77 var d = this.visibleDate;
78 this.visibleDate = new Date(d.getFullYear()+1, d.getMonth(), d.getDate());
79 this.refresh();
80 },
81
82 handleMouseDown : function(e){
83 var target = e.getTarget();
84 if(target != this.element.dom && !YAHOO.util.Dom.isAncestor(this.element.dom, target)){
85 this.hide();
86 }
87 },
88
89 handleKeyDown : function(e){
90 switch(e.browserEvent.keyCode){
91 case e.LEFT:
92 this.showPrevMonth();
93 e.stopEvent();
94 break;
95 case e.RIGHT:
96 this.showNextMonth();
97 e.stopEvent();
98 break;
99 case e.DOWN:
100 this.showPrevYear();
101 e.stopEvent();
102 break;
103 case e.UP:
104 this.showNextYear();
105 e.stopEvent();
106 break;
107 }
108 },
109
110 handleMouseWheel : function(e){
111 var delta = e.getWheelDelta();
112 if(delta > 0){
113 this.showPrevMonth();
114 e.stopEvent();
115 } else if(delta < 0){
116 this.showNextMonth();
117 e.stopEvent();
118 }
119 },
120
121 handleClick : function(e){
122 var d = this.visibleDate;
123 var t = e.getTarget();
124 if(t && t.className){
125 var cls = t.className.split(' ')[0];
126 switch(cls){
127 case 'active':
128 this.handleSelection(new Date(d.getFullYear(), d.getMonth(), parseInt(t.innerHTML)));
129 break;
130 case 'prevday':
131 var p = this.getPrevMonth(d);
132 this.handleSelection(new Date(p.getFullYear(), p.getMonth(), parseInt(t.innerHTML)));
133 break;
134 case 'nextday':
135 var n = this.getNextMonth(d);
136 this.handleSelection(new Date(n.getFullYear(), n.getMonth(), parseInt(t.innerHTML)));
137 break;
138 case 'ypopcal-today':
139 this.handleSelection(new Date());
140 break;
141 case 'next-month':
142 this.showNextMonth();
143 break;
144 case 'prev-month':
145 this.showPrevMonth();
146 break;
147 }
148 }
149 e.stopEvent();
150 },
151
152 selectToday : function(){
153 this.handleSelection(new Date());
154 },
155
156 handleSelection: function(date){
157 this.selectedDate = date;
158 this.callback(date);
159 this.hide();
160 },
161
162 getPrevMonth : function(d){
163 var m = d.getMonth();var y = d.getFullYear();
164 return (m == 0 ? new Date(--y, 11, 1) : new Date(y, --m, 1));
165 },
166
167 getNextMonth : function(d){
168 var m = d.getMonth();var y = d.getFullYear();
169 return (m == 11 ? new Date(++y, 0, 1) : new Date(y, ++m, 1));
170 },
171
172 getDaysInMonth : function(m, y){
173 return (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) ? 31 : (m == 4 || m == 6 || m == 9 || m == 11) ? 30 : this.isLeapYear(y) ? 29 : 28;
174 },
175
176 isLeapYear : function(y){
177 return (((y % 4) == 0) && ((y % 100) != 0) || ((y % 400) == 0));
178 },
179
180 clearTime : function(date){
181 if(date){
182 date.setHours(0);
183 date.setMinutes(0);
184 date.setSeconds(0);
185 date.setMilliseconds(0);
186 }
187 return date;
188 },
189
190 refresh : function(){
191 var d = this.visibleDate;
192 this.buildInnerCal(d);
193 this.calHead.update(this.monthNames[d.getMonth()] + ' ' + d.getFullYear());
194 if(this.element.isVisible()){
195 this.shadow.setRegion(this.element.getRegion());
196 }
197 }
198};
199
200/**
201 * This code is not pretty, but it is fast!
202 * @ignore
203 */
204YAHOO.ext.DatePicker.prototype.buildControl = function(parentElement){
205 var c = document.createElement('div');
206 c.style.position = 'absolute';
207 c.style.visibility = 'hidden';
208 document.body.appendChild(c);
209 var html = '<iframe id="'+this.id+'_shdw" frameborder="0" class="ypopcal-shadow" src="'+YAHOO.ext.SSL_SECURE_URL+'"></iframe>' +
210 '<div hidefocus="true" class="ypopcal" id="'+this.id+'">' +
211 '<table class="ypopcal-head" border=0 cellpadding=0 cellspacing=0><tbody><tr><td class="ypopcal-arrow"><div class="prev-month">&#160;</div></td><td class="ypopcal-month">&#160;</td><td class="ypopcal-arrow"><div class="next-month">&#160;</div></td></tr></tbody></table>' +
212 '<center><div class="ypopcal-inner">';
213 html += "<table border=0 cellspacing=0 class=\"ypopcal-table\"><thead><tr class=\"ypopcal-daynames\">";
214 var names = this.dayNames;
215 for(var i = 0; i < names.length; i++){
216 html += '<td>' + names[i].substr(0, 1) + '</td>';
217 }
218 html+= "</tr></thead><tbody><tr>";
219 for(var i = 0; i < 42; i++) {
220 if(i % 7 == 0 && i != 0){
221 html += '</tr><tr>';
222 }
223 html += "<td>&nbsp;</td>";
224 }
225 html += "</tr></tbody></table>";
226 html += '</div><button class="ypopcal-today">'+this.todayText+'</button></center></div>';
227 c.innerHTML = html;
228 this.shadow = getEl(c.childNodes[0], true);
229 this.shadow.enableDisplayMode('block');
230 this.element = getEl(c.childNodes[1], true);
231 this.element.enableDisplayMode('block');
232 document.body.appendChild(this.shadow.dom);
233 document.body.appendChild(this.element.dom);
234 document.body.removeChild(c);
235 this.element.on("selectstart", function(){return false;});
236 var tbody = this.element.dom.getElementsByTagName('tbody')[1];
237 this.cells = tbody.getElementsByTagName('td');
238 this.calHead = this.element.getChildrenByClassName('ypopcal-month', 'td')[0];
239 this.element.mon('mousedown', this.handleClick, this, true);
240};
241
242YAHOO.ext.DatePicker.prototype.buildInnerCal = function(dateVal){
243 var days = this.getDaysInMonth(dateVal.getMonth() + 1, dateVal.getFullYear());
244 var firstOfMonth = new Date(dateVal.getFullYear(), dateVal.getMonth(), 1);
245 var startingPos = firstOfMonth.getDay();
246 if(startingPos == 0) startingPos = 7;
247 var pm = this.getPrevMonth(dateVal);
248 var prevStart = this.getDaysInMonth(pm.getMonth()+1, pm.getFullYear())-startingPos;
249 var cells = this.cells;
250 days += startingPos;
251
252 // convert everything to numbers so it's fast
253 var day = 86400000;
254 var date = this.clearTime(new Date(pm.getFullYear(), pm.getMonth(), prevStart));
255 var today = this.clearTime(new Date()).getTime();
256 var sel = this.selectedDate ? this.clearTime(this.selectedDate).getTime() : today + 1; //today +1 will never match anything
257 var min = this.minDate ? this.clearTime(this.minDate).getTime() : Number.NEGATIVE_INFINITY;
258 var max = this.maxDate ? this.clearTime(this.maxDate).getTime() : Number.POSITIVE_INFINITY;
259 var ddMatch = this.disabledDatesRE;
260 var ddText = this.disabledDatesText;
261 var ddays = this.disabledDays;
262 var ddaysText = this.disabledDaysText;
263 var format = this.format;
264
265 var setCellClass = function(cal, cell, d){
266 cell.title = '';
267 var t = d.getTime();
268 if(t == today){
269 cell.className += ' today';
270 cell.title = cal.todayText;
271 }
272 if(t == sel){
273 cell.className += ' selected';
274 }
275 // disabling
276 if(t < min) {
277 cell.className = ' ypopcal-disabled';
278 cell.title = cal.minText;
279 return;
280 }
281 if(t > max) {
282 cell.className = ' ypopcal-disabled';
283 cell.title = cal.maxText;
284 return;
285 }
286 if(ddays){
287 var day = d.getDay();
288 for(var i = 0; i < ddays.length; i++) {
289 if(day === ddays[i]){
290 cell.title = ddaysText;
291 cell.className = ' ypopcal-disabled';
292 return;
293 }
294 }
295 }
296 if(ddMatch && format){
297 var fvalue = d.format(format);
298 if(ddMatch.test(fvalue)){
299 cell.title = ddText.replace('%0', fvalue);
300 cell.className = ' ypopcal-disabled';
301 return;
302 }
303 }
304 };
305
306 var i = 0;
307 for(; i < startingPos; i++) {
308 cells[i].innerHTML = (++prevStart);
309 date.setDate(date.getDate()+1);
310 cells[i].className = 'prevday';
311 setCellClass(this, cells[i], date);
312 }
313 for(; i < days; i++){
314 intDay = i - startingPos + 1;
315 cells[i].innerHTML = (intDay);
316 date.setDate(date.getDate()+1);
317 cells[i].className = 'active';
318 setCellClass(this, cells[i], date);
319 }
320 var extraDays = 0;
321 for(; i < 42; i++) {
322 cells[i].innerHTML = (++extraDays);
323 date.setDate(date.getDate()+1);
324 cells[i].className = 'nextday';
325 setCellClass(this, cells[i], date);
326 }
327};
328
329YAHOO.ext.DatePicker.prototype.todayText = "Today";
330YAHOO.ext.DatePicker.prototype.minDate = null;
331YAHOO.ext.DatePicker.prototype.maxDate = null;
332YAHOO.ext.DatePicker.prototype.minText = "This date is before the minimum date";
333YAHOO.ext.DatePicker.prototype.maxText = "This date is after the maximum date";
334YAHOO.ext.DatePicker.prototype.format = 'm/d/y';
335YAHOO.ext.DatePicker.prototype.disabledDays = null;
336YAHOO.ext.DatePicker.prototype.disabledDaysText = '';
337YAHOO.ext.DatePicker.prototype.disabledDatesRE = null;
338YAHOO.ext.DatePicker.prototype.disabledDatesText = '';
339YAHOO.ext.DatePicker.prototype.constrainToViewport = true;
340
341
342YAHOO.ext.DatePicker.prototype.monthNames = Date.monthNames;
343
344YAHOO.ext.DatePicker.prototype.dayNames = Date.dayNames;