mform-dateselector MDL-23829 Removed patch to fix YUI issue that was fixed in 3.2.0
[moodle.git] / lib / form / yui / dateselector / dateselector.js
1 YUI.add('moodle-form-dateselector', function(Y) {
3     /**
4      * Add some custom methods to the node class to make our lives a little
5      * easier within this module.
6      */
7     Y.mix(Y.Node.prototype, {
8         /**
9          * Gets the value of the first option in the select box
10          */
11         firstOptionValue : function() {
12             if (this.get('nodeName').toLowerCase() != 'select') {
13                 return false;
14             }
15             return this.one('option').get('value');
16         },
17         /**
18          * Gets the value of the last option in the select box
19          */
20         lastOptionValue : function() {
21             if (this.get('nodeName').toLowerCase() != 'select') {
22                 return false;
23             }
24             return this.all('option').item(this.optionSize()-1).get('value');
25         },
26         /**
27          * Gets the number of options in the select box
28          */
29         optionSize : function() {
30             if (this.get('nodeName').toLowerCase() != 'select') {
31                 return false;
32             }
33             return parseInt(this.all('option').size());
34         },
35         /**
36          * Gets the value of the selected option in the select box
37          */
38         selectedOptionValue : function() {
39             if (this.get('nodeName').toLowerCase() != 'select') {
40                 return false;
41             }
42             return this.all('option').item(this.get('selectedIndex')).get('value');
43         }
44     });
46     /**
47      * Calendar class
48      *
49      * This is our main class
50      */
51     var CALENDAR = function(config) {
52         CALENDAR.superclass.constructor.apply(this, arguments);
53     };
54     CALENDAR.prototype = {
55         panel : null,
56         yearselect : null,
57         yearselectchange : null,
58         monthselect : null,
59         monthselectchange : null,
60         dayselect : null,
61         dayselectchange : null,
62         enablecheckbox : null,
63         initializer : function(config) {
64             var controls = this.get('node').all('select');
65             controls.each(function(node){
66                 if (node.get('name').match(/\[year]/)) {
67                     this.yearselect = node;
68                 } else if (node.get('name').match(/\[month\]/)) {
69                     this.monthselect = node;
70                 } else if (node.get('name').match(/\[day]/)) {
71                     this.dayselect = node;
72                 } else {
73                     node.on('focus', M.form.dateselector.cancel_any_timeout, M.form.dateselector);
74                     node.on('blur', this.blur_event, this);
75                     return;
76                 }
77                 node.on('focus', this.focus_event, this);
78                 node.on('click', this.focus_event, this);
79                 node.after('change', this.set_date_from_selects, this);
80             }, this);
82             if (this.yearselect && this.monthselect && this.dayselect) {
83                 this.enablecheckbox = this.get('node').one('input');
84             }
85         },
86         focus_event : function(e) {
87             M.form.dateselector.cancel_any_timeout();
88             if (this.enablecheckbox == null || this.enablecheckbox.get('checked')) {
89                 this.claim_calendar();
90             } else {
91                 if (M.form.dateselector.currentowner) {
92                     M.form.dateselector.currentowner.release_calendar();
93                 }
94             }
95         },
96         blur_event : function(e) {
97             M.form.dateselector.hidetimeout = setTimeout(M.form.dateselector.release_current, 300);
98         },
99         handle_select_change : function(e) {
100             this.set_date_from_selects();
101         },
102         claim_calendar : function() {
103             M.form.dateselector.cancel_any_timeout();
104             if (M.form.dateselector.currentowner == this) {
105                 return;
106             }
107             if (M.form.dateselector.currentowner) {
108                 M.form.dateselector.currentowner.release_calendar();
109             }
111             if (M.form.dateselector.currentowner != this) {
112                 this.connect_handlers();
113                 this.set_date_from_selects();
114             }
115             M.form.dateselector.currentowner = this;
116             M.form.dateselector.calendar.cfg.setProperty('mindate', new Date(this.yearselect.firstOptionValue(), 0, 1));
117             M.form.dateselector.calendar.cfg.setProperty('maxdate', new Date(this.yearselect.lastOptionValue(), 11, 31));
118             M.form.dateselector.panel.set('constrain', this.get('node').ancestor('form'));
119             M.form.dateselector.panel.show();
120             M.form.dateselector.fix_position();
121             setTimeout(function(){M.form.dateselector.cancel_any_timeout()}, 100);
122         },
123         set_date_from_selects : function() {
124             var year = parseInt(this.yearselect.get('value'));
125             var month = parseInt(this.monthselect.get('value')) - 1;
126             var day = parseInt(this.dayselect.get('value'));
127             M.form.dateselector.calendar.select(new Date(year, month, day));
128             M.form.dateselector.calendar.setMonth(month);
129             M.form.dateselector.calendar.setYear(year);
130             M.form.dateselector.calendar.render();
131         },
132         set_selects_from_date : function(eventtype, args) {
133             var date = args[0][0];
134             var newyear = date[0];
135             var newindex = newyear - this.yearselect.firstOptionValue();
136             this.yearselect.set('selectedIndex', newindex);
137             this.monthselect.set('selectedIndex', date[1] - this.monthselect.firstOptionValue());
138             this.dayselect.set('selectedIndex', date[2] - this.dayselect.firstOptionValue());
139         },
140         connect_handlers : function() {
141             M.form.dateselector.calendar.selectEvent.subscribe(this.set_selects_from_date, this, true);
142         },
143         release_calendar : function() {
144             M.form.dateselector.panel.hide();
145             M.form.dateselector.currentowner = null;
146             M.form.dateselector.calendar.selectEvent.unsubscribe(this.set_selects_from_date, this);
147         }
148     };
149     Y.extend(CALENDAR, Y.Base, CALENDAR.prototype, {
150         NAME : 'Date Selector',
151         ATTRS : {
152             firstdayofweek  : {
153                 validator : Y.Lang.isString
154             },
155             node : {
156                 setter : function(node) {
157                     return Y.one(node);
158                 }
159             }
160         }
161     });
163     M.form = M.form || {};
164     M.form.dateselector = {
165         panel : null,
166         calendar : null,
167         currentowner : null,
168         hidetimeout : null,
169         repositiontimeout : null,
170         init_date_selectors : function(config) {
171             if (this.panel === null) {
172                 this.initPanel(config);
173             }
174             Y.all('fieldset.fdate_time_selector').each(function(){
175                 config.node = this;
176                 new CALENDAR(config);
177             });
178             Y.all('fieldset.fdate_selector').each(function(){
179                 config.node = this;
180                 new CALENDAR(config);
181             });
182         },
183         initPanel : function(config) {
184             this.panel = new Y.Overlay({
185                 visible : false,
186                 constrain : true,
187                 bodyContent : Y.Node.create('<div id="dateselector-calendar-content"></div>'),
188                 id : 'dateselector-calendar-panel'
189             });
190             this.panel.render(document.body);
191             this.panel.on('heightChange', this.fix_position, this);
193             Y.one('#dateselector-calendar-panel').on('click', function(e){e.halt();});
194             Y.one(document.body).on('click', this.document_click, this);
196             this.calendar = new YAHOO.widget.Calendar(document.getElementById('dateselector-calendar-content'), {
197                 iframe: false,
198                 hide_blank_weeks: true,
199                 start_weekday: config.firstdayofweek
200             });
201             this.calendar.changePageEvent.subscribe(function(){
202                 this.fix_position();
203             }, this);
204         },
205         cancel_any_timeout : function() {
206             if (this.hidetimeout) {
207                 clearTimeout(this.hidetimeout);
208                 this.hidetimeout = null;
209             }
210             if (this.repositiontimeout) {
211                 clearTimeout(this.repositiontimeout);
212                 this.repositiontimeout = null;
213             }
214         },
215         delayed_reposition : function() {
216             if (this.repositiontimeout) {
217                 clearTimeout(this.repositiontimeout);
218                 this.repositiontimeout = null;
219             }
220             this.repositiontimeout = setTimeout(this.fix_position, 500);
221         },
222         fix_position : function() {
223             if (this.currentowner) {
224                 this.panel.set('constrain', this.currentowner.get('node').ancestor('form'));
225                 this.panel.set('align', {
226                     node:this.currentowner.get('node').one('select'),
227                     points:[Y.WidgetPositionAlign.BL, Y.WidgetPositionAlign.TL]
228                 });
229             }
230         },
231         release_current : function() {
232             if (this.currentowner) {
233                 this.currentowner.release_calendar();
234             }
235         },
236         document_click : function(e) {
237             if (this.currentowner) {
238                 if (this.currentowner.get('node').ancestor('div').contains(e.target)) {
239                     setTimeout(function() {M.form.dateselector.cancel_any_timeout()}, 100);
240                 } else {
241                     this.currentowner.release_calendar();
242                 }
243             }
244         }
245     }
247 }, '@VERSION@', {requires:['base','node','overlay', 'yui2-calendar', 'moodle-form-dateselector-skin']});