r2591 - datepicker: added initial refactor. datepicker now uses the widget factory.

r2591 - datepicker: added initial refactor. datepicker now uses the widget factory.


Author: pazu2k@gmail.com
Date: Wed May 20 11:10:15 2009
New Revision: 2591
Modified:
branches/dev/datepicker/ui/ui.datepicker.js
Log:
datepicker: added initial refactor. datepicker now uses the widget factory.
Modified: branches/dev/datepicker/ui/ui.datepicker.js
==============================================================================
--- branches/dev/datepicker/ui/ui.datepicker.js    (original)
+++ branches/dev/datepicker/ui/ui.datepicker.js    Wed May 20 11:10:15 2009
@@ -11,101 +11,65 @@
*    ui.core.js
*/
-(function($) { // hide the namespace
-
-$.extend($.ui, { datepicker: { version: "@VERSION" } });
+(function($) {
var PROP_NAME = 'datepicker';
-/* Date picker manager.
- Use the singleton instance of this class, $.datepicker, to interact
with the date picker.
- Settings for (groups of) date pickers are maintained in an instance
object,
- allowing multiple different settings on the same page. */
-
-function Datepicker() {
-    this.debug = false; // Change this to true to start debugging
-    this._curInst = null; // The current instance in use
-    this._keyEvent = false; // If the last event was a key event
-    this._disabledInputs = []; // List of date picker inputs that have been
disabled
-    this._datepickerShowing = false; // True if the popup picker is showing ,
false if not
-    this._inDialog = false; // True if showing within a "dialog", false if not
-    this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker
division
-    this._inlineClass = 'ui-datepicker-inline'; // The name of the inline
marker class
-    this._appendClass = 'ui-datepicker-append'; // The name of the append
marker class
-    this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger
marker class
-    this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog
marker class
-    this._disableClass = 'ui-datepicker-disabled'; // The name of the
disabled covering marker class
-    this._unselectableClass = 'ui-datepicker-unselectable'; // The name of
the unselectable cell marker class
-    this._currentClass = 'ui-datepicker-current-day'; // The name of the
current day marker class
-    this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the
day hover marker class
-    this.regional = []; // Available regional settings, indexed by language
code
-    this.regional[''] = { // Default regional settings
-        closeText: 'Done', // Display text for close link
-        prevText: 'Prev', // Display text for previous month link
-        nextText: 'Next', // Display text for next month link
-        currentText: 'Today', // Display text for current month link
-        monthNames: ['January','February','March','April','May','June',
-            'July','August','September','October','November','December'], // Names
of months for drop-down and formatting
-        monthNamesShort:
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
// For formatting
-        dayNames:
['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
// For formatting
-        dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For
formatting
-        dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings
for days starting at Sunday
-        dateFormat: 'mm/dd/yy', // See format options on parseDate
-        firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
-        isRTL: false, // True if right-to-left language, false if left-to-right
-        showMonthAfterYear: false, // True if the year select precedes month,
false for month then year
-        yearSuffix: '' // Additional text to append to the year in the month
headers
-    };
-    this._defaults = { // Global defaults for all the date picker instances
-        showOn: 'focus', // 'focus' for popup on focus,
-            // 'button' for trigger button, or 'both' for either
-        showAnim: 'show', // Name of jQuery animation for popup
-        showOptions: {}, // Options for enhanced animations
-        defaultDate: null, // Used when field is blank: actual date,
-            // +/-number for offset from today, null for today
-        appendText: '', // Display text following the input box, e.g. showing
the format
-        buttonText: '...', // Text for trigger button
-        buttonImage: '', // URL for trigger button image
-        buttonImageOnly: false, // True if the image appears alone, false if it
appears on a button
-        hideIfNoPrevNext: false, // True to hide next/previous month links
-            // if not applicable, false to just disable them
-        navigationAsDateFormat: false, // True if date formatting applied to
prev/today/next links
-        gotoCurrent: false, // True if today link goes back to current selection
instead
-        changeMonth: false, // True if month can be selected directly, false if
only prev/next
-        changeYear: false, // True if year can be selected directly, false if
only prev/next
-        yearRange: '-10:+10', // Range of years to display in drop-down,
-            // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
-        showOtherMonths: false, // True to show dates in other months, false to
leave blank
-        calculateWeek: this.iso8601Week, // How to calculate the week of the
year,
-            // takes a Date and returns the number of the week for it
-        shortYearCutoff: '+10', // Short year values < this are in the current
century,
-            // > this are in the previous century,
-            // string value starting with '+' for current year + value
-        minDate: null, // The earliest selectable date, or null for no limit
-        maxDate: null, // The latest selectable date, or null for no limit
-        duration: 'normal', // Duration of display/closure
-        beforeShowDay: null, // Function that takes a date and returns an array
with
-            // [0] = true if selectable, false if not, [1] = custom CSS class
name(s) or '',
-            // [2] = cell title (optional), e.g. $.datepicker.noWeekends
-        beforeShow: null, // Function that takes an input field and
-            // returns a set of custom settings for the date picker
-        onSelect: null, // Define a callback function when a date is selected
-        onChangeMonthYear: null, // Define a callback function when the month or
year is changed
-        onClose: null, // Define a callback function when the datepicker is
closed
-        numberOfMonths: 1, // Number of months to show at a time
-        showCurrentAtPos: 0, // The position in multipe months at which to show
the current month (starting at 0)
-        stepMonths: 1, // Number of months to step back/forward
-        stepBigMonths: 12, // Number of months to step back/forward for the big
links
-        altField: '', // Selector for an alternate field to store selected dates
into
-        altFormat: '', // The date format to use for the alternate field
-        constrainInput: true, // The input is constrained by the current date
format
-        showButtonPanel: false // True to show button panel, false to not show it
-    };
-    $.extend(this._defaults, this.regional['']);
-    this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker
ui-widget ui-widget-content ui-helper-clearfix ui-corner-all
ui-helper-hidden-accessible"></div>');
-}
-
-$.extend(Datepicker.prototype, {
+$.widget('ui.datepicker', {
+    _init: function() {
+        var self = this, o = this.options;
+
+        this._defaults = o;
+        this.debug = false; // Change this to true to start debugging
+        this._curInst = null; // The current instance in use
+        this._keyEvent = false; // If the last event was a key event
+        this._disabledInputs = []; // List of date picker inputs that have been
disabled
+        this._datepickerShowing = false; // True if the popup picker is
showing , false if not
+        this._inDialog = false; // True if showing within a "dialog", false if
not
+        this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker
division
+        this._inlineClass = 'ui-datepicker-inline'; // The name of the inline
marker class
+        this._appendClass = 'ui-datepicker-append'; // The name of the append
marker class
+        this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger
marker class
+        this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog
marker class
+        this._disableClass = 'ui-datepicker-disabled'; // The name of the
disabled covering marker class
+        this._unselectableClass = 'ui-datepicker-unselectable'; // The name of
the unselectable cell marker class
+        this._currentClass = 'ui-datepicker-current-day'; // The name of the
current day marker class
+        this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the
day hover marker class
+        this.regional = []; // Available regional settings, indexed by language
code
+        this.regional[''] = { // Default regional settings
+            closeText: 'Done', // Display text for close link
+            prevText: 'Prev', // Display text for previous month link
+            nextText: 'Next', // Display text for next month link
+            currentText: 'Today', // Display text for current month link
+            monthNames: ['January','February','March','April','May','June',
+                'July','August','September','October','November','December'], // Names
of months for drop-down and formatting
+            monthNamesShort:
['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
// For formatting
+            dayNames:
['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
// For formatting
+            dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], //
For formatting
+            dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings
for days starting at Sunday
+            dateFormat: 'mm/dd/yy', // See format options on parseDate
+            firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+            isRTL: false, // True if right-to-left language, false if left-to-right
+            showMonthAfterYear: false, // True if the year select precedes month,
false for month then year
+            yearSuffix: '' // Additional text to append to the year in the month
headers
+        };
+    
+        // TODO: move this to the correct place
+        $.extend(this._defaults, this.regional['']);
+        
+        self.dpDiv = $('<div id="' + self._mainDivId + '" class="ui-datepicker
ui-widget ui-widget-content ui-helper-clearfix ui-corner-all
ui-helper-hidden-accessible"></div>');
+        
+        // Initialise the date picker.
+        if (!self.initialized) {
+            $(document).mousedown(function(event){ self._checkExternalClick(event);
})
+                .find('body')
+                .append(self.dpDiv);
+            self.initialized = true;
+        }
+    
+        self._attachDatepicker(self.element[0],o);
+    },
+    
    /* Class name added to elements to indicate already configured with a
date picker. */
    markerClassName: 'hasDatepicker',
@@ -166,7 +130,7 @@
    /* Attach the date picker to an input field. */
    _connectDatepicker: function(target, inst) {
-        var input = $(target);
+        var self = this, input = $(target);
        inst.append = $([]);
        inst.trigger = $([]);
        if (input.hasClass(this.markerClassName))
@@ -178,8 +142,12 @@
            input[isRTL ? 'before' : 'after'](inst.append);
        }
        var showOn = this._get(inst, 'showOn');
-        if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in
the marked field
-            input.focus(this._showDatepicker);
+        // pop-up date picker when in the marked field
+        if (showOn == 'focus' || showOn == 'both') {
+            input.bind('focus', function(event) {
+                self._showDatepicker(this);
+            });
+        }
        if (showOn == 'button' || showOn == 'both') { // pop-up date picker when
button clicked
            var buttonText = this._get(inst, 'buttonText');
            var buttonImage = this._get(inst, 'buttonImage');
@@ -191,19 +159,27 @@
                    { src:buttonImage, alt:buttonText, title:buttonText })));
            input[isRTL ? 'before' : 'after'](inst.trigger);
            inst.trigger.click(function() {
-                if ($.datepicker._datepickerShowing && $.datepicker._lastInput ==
target)
-                    $.datepicker._hideDatepicker();
+                if (self._datepickerShowing && self._lastInput == target)
+                    self._hideDatepicker();
                else
-                    $.datepicker._showDatepicker(target);
+                    self._showDatepicker(target);
                return false;
            });
        }
-        input.addClass(this.markerClassName).keydown(this._doKeyDown).
-            keypress(this._doKeyPress).keyup(this._doKeyUp).
+        input.addClass(this.markerClassName)
+            .keydown(function(event) {
+                self._doKeyDown(event);
+            })
+            .keypress(function(event) {
+                self._doKeyPress(event);
+            })
+            .keyup(function(event) {
+                self._doKeyUp(event);
+            }).
            bind("setData.datepicker", function(event, key, value) {
                inst.settings[key] = value;
            }).bind("getData.datepicker", function(event, key) {
-                return this._get(inst, key);
+                return self._get(inst, key);
            });
        $.data(target, PROP_NAME, inst);
    },
@@ -376,9 +352,9 @@
     @param value any - the new value for the setting
     (omit if above is an object or to retrieve a value) */
    _optionDatepicker: function(target, name, value) {
-        var inst = this._getInst(target);
+        var self = this, inst = self._getInst(target);
        if (arguments.length == 2 && typeof name == 'string') {
-            return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
+            return (name == 'defaults' ? $.extend({}, self._defaults) :
                (inst ? (name == 'all' ? $.extend({}, inst.settings) :
                this._get(inst, name)) : null));
        }
@@ -436,64 +412,66 @@
    /* Handle keystrokes. */
    _doKeyDown: function(event) {
-        var inst = $.datepicker._getInst(event.target);
-        var handled = true;
-        var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
+        var self = this,
+            inst = self._getInst(event.target),
+            handled = true,
+            isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
+    
        inst._keyEvent = true;
-        if ($.datepicker._datepickerShowing)
+        if (self._datepickerShowing)
            switch (event.keyCode) {
-                case 9: $.datepicker._hideDatepicker(null, '');
+                case 9: self._hideDatepicker(null, '');
                        break; // hide on tab out
-                case 13: var sel = $('td.' + $.datepicker._dayOverClass +
-                            ', td.' + $.datepicker._currentClass, inst.dpDiv);
+                case 13: var sel = $('td.' + self._dayOverClass +
+                            ', td.' + self._currentClass, inst.dpDiv);
                        if (sel[0])
-                            $.datepicker._selectDay(event.target, inst.selectedMonth,
inst.selectedYear, sel[0]);
+                            self._selectDay(event.target, inst.selectedMonth,
inst.selectedYear, sel[0]);
                        else
-                            $.datepicker._hideDatepicker(null,
$.datepicker._get(inst, 'duration'));
+                            self._hideDatepicker(null, self._get(inst, 'duration'));
                        return false; // don't submit the form
                        break; // select the value on enter
-                case 27: $.datepicker._hideDatepicker(null,
$.datepicker._get(inst, 'duration'));
+                case 27: self._hideDatepicker(null, self._get(inst, 'duration'));
                        break; // hide on escape
-                case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
-                            -$.datepicker._get(inst, 'stepBigMonths') :
-                            -$.datepicker._get(inst, 'stepMonths')), 'M');
+                case 33: self._adjustDate(event.target, (event.ctrlKey ?
+                            -self._get(inst, 'stepBigMonths') :
+                            -self._get(inst, 'stepMonths')), 'M');
                        break; // previous month/year on page up/+ ctrl
-                case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
-                            +$.datepicker._get(inst, 'stepBigMonths') :
-                            +$.datepicker._get(inst, 'stepMonths')), 'M');
+                case 34: self._adjustDate(event.target, (event.ctrlKey ?
+                            +self._get(inst, 'stepBigMonths') :
+                            +self._get(inst, 'stepMonths')), 'M');
                        break; // next month/year on page down/+ ctrl
-                case 35: if (event.ctrlKey || event.metaKey)
$.datepicker._clearDate(event.target);
+                case 35: if (event.ctrlKey || event.metaKey)
self._clearDate(event.target);
                        handled = event.ctrlKey || event.metaKey;
                        break; // clear on ctrl or command +end
-                case 36: if (event.ctrlKey || event.metaKey)
$.datepicker._gotoToday(event.target);
+                case 36: if (event.ctrlKey || event.metaKey)
self._gotoToday(event.target);
                        handled = event.ctrlKey || event.metaKey;
                        break; // current on ctrl or command +home
-                case 37: if (event.ctrlKey || event.metaKey)
$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
+                case 37: if (event.ctrlKey || event.metaKey)
self._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
                        handled = event.ctrlKey || event.metaKey;
                        // -1 day on ctrl or command +left
-                        if (event.originalEvent.altKey)
$.datepicker._adjustDate(event.target, (event.ctrlKey ?
-                                    -$.datepicker._get(inst, 'stepBigMonths') :
-                                    -$.datepicker._get(inst, 'stepMonths')), 'M');
+                        if (event.originalEvent.altKey) self._adjustDate(event.target,
(event.ctrlKey ?
+                                    -self._get(inst, 'stepBigMonths') :
+                                    -self._get(inst, 'stepMonths')), 'M');
                        // next month/year on alt +left on Mac
                        break;
-                case 38: if (event.ctrlKey || event.metaKey)
$.datepicker._adjustDate(event.target, -7, 'D');
+                case 38: if (event.ctrlKey || event.metaKey)
self._adjustDate(event.target, -7, 'D');
                        handled = event.ctrlKey || event.metaKey;
                        break; // -1 week on ctrl or command +up
-                case 39: if (event.ctrlKey || event.metaKey)
$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
+                case 39: if (event.ctrlKey || event.metaKey)
self._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
                        handled = event.ctrlKey || event.metaKey;
                        // +1 day on ctrl or command +right
-                        if (event.originalEvent.altKey)
$.datepicker._adjustDate(event.target, (event.ctrlKey ?
-                     &n