source: trunk/web/addons/job_monarch/lib/extjs/source/widgets/DatePicker.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 25.3 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.DatePicker
11 * @extends Ext.Component
12 * Simple date picker class.
13 * @constructor
14 * Create a new DatePicker
15 * @param {Object} config The config object
16 */
17Ext.DatePicker = Ext.extend(Ext.Component, {
18    /**
19     * @cfg {String} todayText
20     * The text to display on the button that selects the current date (defaults to "Today")
21     */
22    todayText : "Today",
23    /**
24     * @cfg {String} okText
25     * The text to display on the ok button
26     */
27    okText : " OK ", //   to give the user extra clicking room
28    /**
29     * @cfg {String} cancelText
30     * The text to display on the cancel button
31     */
32    cancelText : "Cancel",
33    /**
34     * @cfg {String} todayTip
35     * The tooltip to display for the button that selects the current date (defaults to "{current date} (Spacebar)")
36     */
37    todayTip : "{0} (Spacebar)",
38    /**
39     * @cfg {String} minText
40     * The error text to display if the minDate validation fails (defaults to "This date is before the minimum date")
41     */
42    minText : "This date is before the minimum date",
43    /**
44     * @cfg {String} maxText
45     * The error text to display if the maxDate validation fails (defaults to "This date is after the maximum date")
46     */
47    maxText : "This date is after the maximum date",
48    /**
49     * @cfg {String} format
50     * The default date format string which can be overriden for localization support.  The format must be
51     * valid according to {@link Date#parseDate} (defaults to 'm/d/y').
52     */
53    format : "m/d/y",
54    /**
55     * @cfg {String} disabledDaysText
56     * The tooltip to display when the date falls on a disabled day (defaults to "Disabled")
57     */
58    disabledDaysText : "Disabled",
59    /**
60     * @cfg {String} disabledDatesText
61     * The tooltip text to display when the date falls on a disabled date (defaults to "Disabled")
62     */
63    disabledDatesText : "Disabled",
64    /**
65     * @cfg {Boolean} constrainToViewport
66     * <b>Deprecated</b> (not currently used). True to constrain the date picker to the viewport (defaults to true)
67     */
68    constrainToViewport : true,
69    /**
70     * @cfg {Array} monthNames
71     * An array of textual month names which can be overriden for localization support (defaults to Date.monthNames)
72     */
73    monthNames : Date.monthNames,
74    /**
75     * @cfg {Array} dayNames
76     * An array of textual day names which can be overriden for localization support (defaults to Date.dayNames)
77     */
78    dayNames : Date.dayNames,
79    /**
80     * @cfg {String} nextText
81     * The next month navigation button tooltip (defaults to 'Next Month (Control+Right)')
82     */
83    nextText: 'Next Month (Control+Right)',
84    /**
85     * @cfg {String} prevText
86     * The previous month navigation button tooltip (defaults to 'Previous Month (Control+Left)')
87     */
88    prevText: 'Previous Month (Control+Left)',
89    /**
90     * @cfg {String} monthYearText
91     * The header month selector tooltip (defaults to 'Choose a month (Control+Up/Down to move years)')
92     */
93    monthYearText: 'Choose a month (Control+Up/Down to move years)',
94    /**
95     * @cfg {Number} startDay
96     * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
97     */
98    startDay : 0,
99    /**
100     * @cfg {Boolean} showToday
101     * False to hide the footer area containing the Today button and disable the keyboard handler for spacebar
102     * that selects the current date (defaults to true).
103     */
104    showToday : true,
105    /**
106     * @cfg {Date} minDate
107     * Minimum allowable date (JavaScript date object, defaults to null)
108     */
109    /**
110     * @cfg {Date} maxDate
111     * Maximum allowable date (JavaScript date object, defaults to null)
112     */
113    /**
114     * @cfg {Array} disabledDays
115     * An array of days to disable, 0-based. For example, [0, 6] disables Sunday and Saturday (defaults to null).
116     */
117    /**
118     * @cfg {RegExp} disabledDatesRE
119     * JavaScript regular expression used to disable a pattern of dates (defaults to null).  The {@link #disabledDates}
120     * config will generate this regex internally, but if you specify disabledDatesRE it will take precedence over the
121     * disabledDates value.
122     */
123    /**
124     * @cfg {Array} disabledDates
125     * An array of "dates" to disable, as strings. These strings will be used to build a dynamic regular
126     * expression so they are very powerful. Some examples:
127     * <ul>
128     * <li>["03/08/2003", "09/16/2003"] would disable those exact dates</li>
129     * <li>["03/08", "09/16"] would disable those days for every year</li>
130     * <li>["^03/08"] would only match the beginning (useful if you are using short years)</li>
131     * <li>["03/../2006"] would disable every day in March 2006</li>
132     * <li>["^03"] would disable every day in every March</li>
133     * </ul>
134     * Note that the format of the dates included in the array should exactly match the {@link #format} config.
135     * In order to support regular expressions, if you are using a date format that has "." in it, you will have to
136     * escape the dot when restricting dates. For example: ["03\\.08\\.03"].
137     */
138
139    // private
140    initComponent : function(){
141        Ext.DatePicker.superclass.initComponent.call(this);
142
143        this.value = this.value ?
144                 this.value.clearTime() : new Date().clearTime();
145
146        this.addEvents(
147            /**
148             * @event select
149             * Fires when a date is selected
150             * @param {DatePicker} this
151             * @param {Date} date The selected date
152             */
153            'select'
154        );
155
156        if(this.handler){
157            this.on("select", this.handler,  this.scope || this);
158        }
159
160        this.initDisabledDays();
161    },
162
163    // private
164    initDisabledDays : function(){
165        if(!this.disabledDatesRE && this.disabledDates){
166            var dd = this.disabledDates;
167            var re = "(?:";
168            for(var i = 0; i < dd.length; i++){
169                re += dd[i];
170                if(i != dd.length-1) re += "|";
171            }
172            this.disabledDatesRE = new RegExp(re + ")");
173        }
174    },
175   
176    /**
177     * Replaces any existing disabled dates with new values and refreshes the DatePicker.
178     * @param {Array/RegExp} disabledDates An array of date strings (see the {@link #disabledDates} config
179     * for details on supported values), or a JavaScript regular expression used to disable a pattern of dates.
180     */
181    setDisabledDates : function(dd){
182        if(Ext.isArray(dd)){
183            this.disabledDates = dd;
184            this.disabledDatesRE = null;
185        }else{
186            this.disabledDatesRE = dd;
187        }
188        this.initDisabledDays();
189        this.update(this.value, true);
190    },
191   
192    /**
193     * Replaces any existing disabled days (by index, 0-6) with new values and refreshes the DatePicker.
194     * @param {Array} disabledDays An array of disabled day indexes. See the {@link #disabledDays} config
195     * for details on supported values.
196     */
197    setDisabledDays : function(dd){
198        this.disabledDays = dd;
199        this.update(this.value, true);
200    },
201   
202    /**
203     * Replaces any existing {@link #minDate} with the new value and refreshes the DatePicker.
204     * @param {Date} value The minimum date that can be selected
205     */
206    setMinDate : function(dt){
207        this.minDate = dt;
208        this.update(this.value, true);
209    },
210   
211    /**
212     * Replaces any existing {@link #maxDate} with the new value and refreshes the DatePicker.
213     * @param {Date} value The maximum date that can be selected
214     */
215    setMaxDate : function(dt){
216        this.maxDate = dt;
217        this.update(this.value, true);
218    },
219
220    /**
221     * Sets the value of the date field
222     * @param {Date} value The date to set
223     */
224    setValue : function(value){
225        var old = this.value;
226        this.value = value.clearTime(true);
227        if(this.el){
228            this.update(this.value);
229        }
230    },
231
232    /**
233     * Gets the current selected value of the date field
234     * @return {Date} The selected date
235     */
236    getValue : function(){
237        return this.value;
238    },
239
240    // private
241    focus : function(){
242        if(this.el){
243            this.update(this.activeDate);
244        }
245    },
246
247    // private
248    onRender : function(container, position){
249        var m = [
250             '<table cellspacing="0">',
251                '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',
252                '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
253        var dn = this.dayNames;
254        for(var i = 0; i < 7; i++){
255            var d = this.startDay+i;
256            if(d > 6){
257                d = d-7;
258            }
259            m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
260        }
261        m[m.length] = "</tr></thead><tbody><tr>";
262        for(var i = 0; i < 42; i++) {
263            if(i % 7 == 0 && i != 0){
264                m[m.length] = "</tr><tr>";
265            }
266            m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
267        }
268        m.push('</tr></tbody></table></td></tr>', 
269                this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '', 
270                '</table><div class="x-date-mp"></div>');
271
272        var el = document.createElement("div");
273        el.className = "x-date-picker";
274        el.innerHTML = m.join("");
275
276        container.dom.insertBefore(el, position);
277
278        this.el = Ext.get(el);
279        this.eventEl = Ext.get(el.firstChild);
280
281        this.leftClickRpt = new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
282            handler: this.showPrevMonth,
283            scope: this,
284            preventDefault:true,
285            stopDefault:true
286        });
287
288        this.rightClickRpt = new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
289            handler: this.showNextMonth,
290            scope: this,
291            preventDefault:true,
292            stopDefault:true
293        });
294
295        this.eventEl.on("mousewheel", this.handleMouseWheel,  this);
296
297        this.monthPicker = this.el.down('div.x-date-mp');
298        this.monthPicker.enableDisplayMode('block');
299       
300        var kn = new Ext.KeyNav(this.eventEl, {
301            "left" : function(e){
302                e.ctrlKey ?
303                    this.showPrevMonth() :
304                    this.update(this.activeDate.add("d", -1));
305            },
306
307            "right" : function(e){
308                e.ctrlKey ?
309                    this.showNextMonth() :
310                    this.update(this.activeDate.add("d", 1));
311            },
312
313            "up" : function(e){
314                e.ctrlKey ?
315                    this.showNextYear() :
316                    this.update(this.activeDate.add("d", -7));
317            },
318
319            "down" : function(e){
320                e.ctrlKey ?
321                    this.showPrevYear() :
322                    this.update(this.activeDate.add("d", 7));
323            },
324
325            "pageUp" : function(e){
326                this.showNextMonth();
327            },
328
329            "pageDown" : function(e){
330                this.showPrevMonth();
331            },
332
333            "enter" : function(e){
334                e.stopPropagation();
335                return true;
336            },
337
338            scope : this
339        });
340
341        this.eventEl.on("click", this.handleDateClick,  this, {delegate: "a.x-date-date"});
342
343        this.el.unselectable();
344       
345        this.cells = this.el.select("table.x-date-inner tbody td");
346        this.textNodes = this.el.query("table.x-date-inner tbody span");
347
348        this.mbtn = new Ext.Button({
349            text: "&#160;",
350            tooltip: this.monthYearText,
351            renderTo: this.el.child("td.x-date-middle", true)
352        });
353
354        this.mbtn.on('click', this.showMonthPicker, this);
355        this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");
356
357        if(this.showToday){
358            this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);
359            var today = (new Date()).dateFormat(this.format);
360            this.todayBtn = new Ext.Button({
361                renderTo: this.el.child("td.x-date-bottom", true),
362                text: String.format(this.todayText, today),
363                tooltip: String.format(this.todayTip, today),
364                handler: this.selectToday,
365                scope: this
366            });
367        }
368       
369        if(Ext.isIE){
370            this.el.repaint();
371        }
372        this.update(this.value);
373    },
374
375    // private
376    createMonthPicker : function(){
377        if(!this.monthPicker.dom.firstChild){
378            var buf = ['<table border="0" cellspacing="0">'];
379            for(var i = 0; i < 6; i++){
380                buf.push(
381                    '<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
382                    '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
383                    i == 0 ?
384                    '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
385                    '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
386                );
387            }
388            buf.push(
389                '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
390                    this.okText,
391                    '</button><button type="button" class="x-date-mp-cancel">',
392                    this.cancelText,
393                    '</button></td></tr>',
394                '</table>'
395            );
396            this.monthPicker.update(buf.join(''));
397            this.monthPicker.on('click', this.onMonthClick, this);
398            this.monthPicker.on('dblclick', this.onMonthDblClick, this);
399
400            this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
401            this.mpYears = this.monthPicker.select('td.x-date-mp-year');
402
403            this.mpMonths.each(function(m, a, i){
404                i += 1;
405                if((i%2) == 0){
406                    m.dom.xmonth = 5 + Math.round(i * .5);
407                }else{
408                    m.dom.xmonth = Math.round((i-1) * .5);
409                }
410            });
411        }
412    },
413
414    // private
415    showMonthPicker : function(){
416        this.createMonthPicker();
417        var size = this.el.getSize();
418        this.monthPicker.setSize(size);
419        this.monthPicker.child('table').setSize(size);
420
421        this.mpSelMonth = (this.activeDate || this.value).getMonth();
422        this.updateMPMonth(this.mpSelMonth);
423        this.mpSelYear = (this.activeDate || this.value).getFullYear();
424        this.updateMPYear(this.mpSelYear);
425
426        this.monthPicker.slideIn('t', {duration:.2});
427    },
428
429    // private
430    updateMPYear : function(y){
431        this.mpyear = y;
432        var ys = this.mpYears.elements;
433        for(var i = 1; i <= 10; i++){
434            var td = ys[i-1], y2;
435            if((i%2) == 0){
436                y2 = y + Math.round(i * .5);
437                td.firstChild.innerHTML = y2;
438                td.xyear = y2;
439            }else{
440                y2 = y - (5-Math.round(i * .5));
441                td.firstChild.innerHTML = y2;
442                td.xyear = y2;
443            }
444            this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
445        }
446    },
447
448    // private
449    updateMPMonth : function(sm){
450        this.mpMonths.each(function(m, a, i){
451            m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
452        });
453    },
454
455    // private
456    selectMPMonth: function(m){
457       
458    },
459
460    // private
461    onMonthClick : function(e, t){
462        e.stopEvent();
463        var el = new Ext.Element(t), pn;
464        if(el.is('button.x-date-mp-cancel')){
465            this.hideMonthPicker();
466        }
467        else if(el.is('button.x-date-mp-ok')){
468            var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
469            if(d.getMonth() != this.mpSelMonth){
470                // "fix" the JS rolling date conversion if needed
471                d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
472            }
473            this.update(d);
474            this.hideMonthPicker();
475        }
476        else if(pn = el.up('td.x-date-mp-month', 2)){
477            this.mpMonths.removeClass('x-date-mp-sel');
478            pn.addClass('x-date-mp-sel');
479            this.mpSelMonth = pn.dom.xmonth;
480        }
481        else if(pn = el.up('td.x-date-mp-year', 2)){
482            this.mpYears.removeClass('x-date-mp-sel');
483            pn.addClass('x-date-mp-sel');
484            this.mpSelYear = pn.dom.xyear;
485        }
486        else if(el.is('a.x-date-mp-prev')){
487            this.updateMPYear(this.mpyear-10);
488        }
489        else if(el.is('a.x-date-mp-next')){
490            this.updateMPYear(this.mpyear+10);
491        }
492    },
493
494    // private
495    onMonthDblClick : function(e, t){
496        e.stopEvent();
497        var el = new Ext.Element(t), pn;
498        if(pn = el.up('td.x-date-mp-month', 2)){
499            this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
500            this.hideMonthPicker();
501        }
502        else if(pn = el.up('td.x-date-mp-year', 2)){
503            this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
504            this.hideMonthPicker();
505        }
506    },
507
508    // private
509    hideMonthPicker : function(disableAnim){
510        if(this.monthPicker){
511            if(disableAnim === true){
512                this.monthPicker.hide();
513            }else{
514                this.monthPicker.slideOut('t', {duration:.2});
515            }
516        }
517    },
518
519    // private
520    showPrevMonth : function(e){
521        this.update(this.activeDate.add("mo", -1));
522    },
523
524    // private
525    showNextMonth : function(e){
526        this.update(this.activeDate.add("mo", 1));
527    },
528
529    // private
530    showPrevYear : function(){
531        this.update(this.activeDate.add("y", -1));
532    },
533
534    // private
535    showNextYear : function(){
536        this.update(this.activeDate.add("y", 1));
537    },
538
539    // private
540    handleMouseWheel : function(e){
541        var delta = e.getWheelDelta();
542        if(delta > 0){
543            this.showPrevMonth();
544            e.stopEvent();
545        } else if(delta < 0){
546            this.showNextMonth();
547            e.stopEvent();
548        }
549    },
550
551    // private
552    handleDateClick : function(e, t){
553        e.stopEvent();
554        if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
555            this.setValue(new Date(t.dateValue));
556            this.fireEvent("select", this, this.value);
557        }
558    },
559
560    // private
561    selectToday : function(){
562        if(this.todayBtn && !this.todayBtn.disabled){
563                this.setValue(new Date().clearTime());
564                this.fireEvent("select", this, this.value);
565        }
566    },
567
568    // private
569    update : function(date, forceRefresh){
570        var vd = this.activeDate;
571        this.activeDate = date;
572        if(!forceRefresh && vd && this.el){
573            var t = date.getTime();
574            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
575                this.cells.removeClass("x-date-selected");
576                this.cells.each(function(c){
577                   if(c.dom.firstChild.dateValue == t){
578                       c.addClass("x-date-selected");
579                       setTimeout(function(){
580                            try{c.dom.firstChild.focus();}catch(e){}
581                       }, 50);
582                       return false;
583                   }
584                });
585                return;
586            }
587        }
588        var days = date.getDaysInMonth();
589        var firstOfMonth = date.getFirstDateOfMonth();
590        var startingPos = firstOfMonth.getDay()-this.startDay;
591
592        if(startingPos <= this.startDay){
593            startingPos += 7;
594        }
595
596        var pm = date.add("mo", -1);
597        var prevStart = pm.getDaysInMonth()-startingPos;
598
599        var cells = this.cells.elements;
600        var textEls = this.textNodes;
601        days += startingPos;
602
603        // convert everything to numbers so it's fast
604        var day = 86400000;
605        var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
606        var today = new Date().clearTime().getTime();
607        var sel = date.clearTime().getTime();
608        var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
609        var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
610        var ddMatch = this.disabledDatesRE;
611        var ddText = this.disabledDatesText;
612        var ddays = this.disabledDays ? this.disabledDays.join("") : false;
613        var ddaysText = this.disabledDaysText;
614        var format = this.format;
615       
616        if(this.showToday){
617            var td = new Date().clearTime();
618            var disable = (td < min || td > max || 
619                (ddMatch && format && ddMatch.test(td.dateFormat(format))) || 
620                (ddays && ddays.indexOf(td.getDay()) != -1));
621                       
622            this.todayBtn.setDisabled(disable);
623            this.todayKeyListener[disable ? 'disable' : 'enable']();
624        }
625
626        var setCellClass = function(cal, cell){
627            cell.title = "";
628            var t = d.getTime();
629            cell.firstChild.dateValue = t;
630            if(t == today){
631                cell.className += " x-date-today";
632                cell.title = cal.todayText;
633            }
634            if(t == sel){
635                cell.className += " x-date-selected";
636                setTimeout(function(){
637                    try{cell.firstChild.focus();}catch(e){}
638                }, 50);
639            }
640            // disabling
641            if(t < min) {
642                cell.className = " x-date-disabled";
643                cell.title = cal.minText;
644                return;
645            }
646            if(t > max) {
647                cell.className = " x-date-disabled";
648                cell.title = cal.maxText;
649                return;
650            }
651            if(ddays){
652                if(ddays.indexOf(d.getDay()) != -1){
653                    cell.title = ddaysText;
654                    cell.className = " x-date-disabled";
655                }
656            }
657            if(ddMatch && format){
658                var fvalue = d.dateFormat(format);
659                if(ddMatch.test(fvalue)){
660                    cell.title = ddText.replace("%0", fvalue);
661                    cell.className = " x-date-disabled";
662                }
663            }
664        };
665
666        var i = 0;
667        for(; i < startingPos; i++) {
668            textEls[i].innerHTML = (++prevStart);
669            d.setDate(d.getDate()+1);
670            cells[i].className = "x-date-prevday";
671            setCellClass(this, cells[i]);
672        }
673        for(; i < days; i++){
674            var intDay = i - startingPos + 1;
675            textEls[i].innerHTML = (intDay);
676            d.setDate(d.getDate()+1);
677            cells[i].className = "x-date-active";
678            setCellClass(this, cells[i]);
679        }
680        var extraDays = 0;
681        for(; i < 42; i++) {
682             textEls[i].innerHTML = (++extraDays);
683             d.setDate(d.getDate()+1);
684             cells[i].className = "x-date-nextday";
685             setCellClass(this, cells[i]);
686        }
687
688        this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
689
690        if(!this.internalRender){
691            var main = this.el.dom.firstChild;
692            var w = main.offsetWidth;
693            this.el.setWidth(w + this.el.getBorderWidth("lr"));
694            Ext.fly(main).setWidth(w);
695            this.internalRender = true;
696            // opera does not respect the auto grow header center column
697            // then, after it gets a width opera refuses to recalculate
698            // without a second pass
699            if(Ext.isOpera && !this.secondPass){
700                main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
701                this.secondPass = true;
702                this.update.defer(10, this, [date]);
703            }
704        }
705    },
706
707    // private
708    beforeDestroy : function() {
709        if(this.rendered){
710            Ext.destroy(
711                this.leftClickRpt,
712                this.rightClickRpt,
713                this.monthPicker,
714                this.eventEl,
715                this.mbtn,
716                this.todayBtn
717            );
718        }
719    }
720
721    /**
722     * @cfg {String} autoEl @hide
723     */
724});
725Ext.reg('datepicker', Ext.DatePicker);
Note: See TracBrowser for help on using the repository browser.