source: Dev/trunk/src/client/dijit/form/_DateTimeTextBox.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 9.4 KB
Line 
1define([
2        "dojo/date", // date date.compare
3        "dojo/date/locale", // locale.regexp
4        "dojo/date/stamp", // stamp.fromISOString stamp.toISOString
5        "dojo/_base/declare", // declare
6        "dojo/_base/lang", // lang.getObject
7        "./RangeBoundTextBox",
8        "../_HasDropDown",
9        "dojo/text!./templates/DropDownBox.html"
10], function(date, locale, stamp, declare, lang, RangeBoundTextBox, _HasDropDown, template){
11
12        // module:
13        //              dijit/form/_DateTimeTextBox
14
15        new Date("X"); // workaround for #11279, new Date("") == NaN
16
17        var _DateTimeTextBox = declare("dijit.form._DateTimeTextBox", [RangeBoundTextBox, _HasDropDown], {
18                // summary:
19                //              Base class for validating, serializable, range-bound date or time text box.
20
21                templateString: template,
22
23                // hasDownArrow: [const] Boolean
24                //              Set this textbox to display a down arrow button, to open the drop down list.
25                hasDownArrow: true,
26
27                // Set classes like dijitDownArrowButtonHover depending on mouse action over button node
28                cssStateNodes: {
29                        "_buttonNode": "dijitDownArrowButton"
30                },
31
32                /*=====
33                // constraints: _DateTimeTextBox.__Constraints
34                //              Despite the name, this parameter specifies both constraints on the input
35                //              (including starting/ending dates/times allowed) as well as
36                //              formatting options like whether the date is displayed in long (ex: December 25, 2005)
37                //              or short (ex: 12/25/2005) format.  See `dijit/form/_DateTimeTextBox.__Constraints` for details.
38                constraints: {},
39                ======*/
40
41                // Override ValidationTextBox.pattern.... we use a reg-ex generating function rather
42                // than a straight regexp to deal with locale  (plus formatting options too?)
43                pattern: locale.regexp,
44
45                // datePackage: String
46                //              JavaScript namespace to find calendar routines.  If unspecified, uses Gregorian calendar routines
47                //              at dojo/date and dojo/date/locale.
48                datePackage: "",
49                //              TODO: for 2.0, replace datePackage with dateModule and dateLocalModule attributes specifying MIDs,
50                //              or alternately just get rid of this completely and tell user to use module ID remapping
51                //              via require
52
53                postMixInProperties: function(){
54                        this.inherited(arguments);
55                        this._set("type", "text"); // in case type="date"|"time" was specified which messes up parse/format
56                },
57
58                // Override _FormWidget.compare() to work for dates/times
59                compare: function(/*Date*/ val1, /*Date*/ val2){
60                        var isInvalid1 = this._isInvalidDate(val1);
61                        var isInvalid2 = this._isInvalidDate(val2);
62                        return isInvalid1 ? (isInvalid2 ? 0 : -1) : (isInvalid2 ? 1 : date.compare(val1, val2, this._selector));
63                },
64
65                // flag to _HasDropDown to make drop down Calendar width == <input> width
66                autoWidth: true,
67
68                format: function(/*Date*/ value, /*locale.__FormatOptions*/ constraints){
69                        // summary:
70                        //              Formats the value as a Date, according to specified locale (second argument)
71                        // tags:
72                        //              protected
73                        if(!value){ return ''; }
74                        return this.dateLocaleModule.format(value, constraints);
75                },
76
77                "parse": function(/*String*/ value, /*locale.__FormatOptions*/ constraints){
78                        // summary:
79                        //              Parses as string as a Date, according to constraints
80                        // tags:
81                        //              protected
82
83                        return this.dateLocaleModule.parse(value, constraints) || (this._isEmpty(value) ? null : undefined);     // Date
84                },
85
86                // Overrides ValidationTextBox.serialize() to serialize a date in canonical ISO format.
87                serialize: function(/*anything*/ val, /*Object?*/ options){
88                        if(val.toGregorian){
89                                val = val.toGregorian();
90                        }
91                        return stamp.toISOString(val, options);
92                },
93
94                // dropDownDefaultValue: Date
95                //              The default value to focus in the popupClass widget when the textbox value is empty.
96                dropDownDefaultValue : new Date(),
97
98                // value: Date
99                //              The value of this widget as a JavaScript Date object.  Use get("value") / set("value", val) to manipulate.
100                //              When passed to the parser in markup, must be specified according to `dojo/date/stamp.fromISOString()`
101                value: new Date(""),    // value.toString()="NaN"
102
103                _blankValue: null,      // used by filter() when the textbox is blank
104
105                // popupClass: [protected extension] String
106                //              Name of the popup widget class used to select a date/time.
107                //              Subclasses should specify this.
108                popupClass: "", // default is no popup = text only
109
110
111                // _selector: [protected extension] String
112                //              Specifies constraints.selector passed to dojo.date functions, should be either
113                //              "date" or "time".
114                //              Subclass must specify this.
115                _selector: "",
116
117                constructor: function(params /*===== , srcNodeRef =====*/){
118                        // summary:
119                        //              Create the widget.
120                        // params: Object|null
121                        //              Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
122                        //              and functions, typically callbacks like onClick.
123                        //              The hash can contain any of the widget's properties, excluding read-only properties.
124                        // srcNodeRef: DOMNode|String?
125                        //              If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
126
127                        this.dateModule = params.datePackage ? lang.getObject(params.datePackage, false) : date;
128                        this.dateClassObj = this.dateModule.Date || Date;
129                        this.dateLocaleModule = params.datePackage ? lang.getObject(params.datePackage+".locale", false) : locale;
130                        this._set('pattern', this.dateLocaleModule.regexp);
131                        this._invalidDate = this.constructor.prototype.value.toString();
132                },
133
134                buildRendering: function(){
135                        this.inherited(arguments);
136
137                        if(!this.hasDownArrow){
138                                this._buttonNode.style.display = "none";
139                        }
140
141                        // If hasDownArrow is false, we basically just want to treat the whole widget as the
142                        // button.
143                        if(!this.hasDownArrow){
144                                this._buttonNode = this.domNode;
145                                this.baseClass += " dijitComboBoxOpenOnClick";
146                        }
147                },
148
149                _setConstraintsAttr: function(/*Object*/ constraints){
150                        constraints.selector = this._selector;
151                        constraints.fullYear = true; // see #5465 - always format with 4-digit years
152                        var fromISO = stamp.fromISOString;
153                        if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); }
154                        if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
155                        this.inherited(arguments);
156                },
157
158                _isInvalidDate: function(/*Date*/ value){
159                        // summary:
160                        //              Runs various tests on the value, checking for invalid conditions
161                        // tags:
162                        //              private
163                        return !value || isNaN(value) || typeof value != "object" || value.toString() == this._invalidDate;
164                },
165
166                _setValueAttr: function(/*Date|String*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
167                        // summary:
168                        //              Sets the date on this textbox. Note: value can be a JavaScript Date literal or a string to be parsed.
169                        if(value !== undefined){
170                                if(typeof value == "string"){
171                                        value = stamp.fromISOString(value);
172                                }
173                                if(this._isInvalidDate(value)){
174                                        value = null;
175                                }
176                                if(value instanceof Date && !(this.dateClassObj instanceof Date)){
177                                        value = new this.dateClassObj(value);
178                                }
179                        }
180                        this.inherited(arguments);
181                        if(this.value instanceof Date){
182                                this.filterString = "";
183                        }
184                        if(this.dropDown){
185                                this.dropDown.set('value', value, false);
186                        }
187                },
188
189                _set: function(attr, value){
190                        // Avoid spurious watch() notifications when value is changed to new Date object w/the same value
191                        var oldValue = this._get("value");
192                        if(attr == "value" && oldValue instanceof Date && this.compare(value, oldValue) == 0){
193                                return;
194                        }
195                        this.inherited(arguments);
196                },
197
198                _setDropDownDefaultValueAttr: function(/*Date*/ val){
199                        if(this._isInvalidDate(val)){
200                                // convert null setting into today's date, since there needs to be *some* default at all times.
201                                 val = new this.dateClassObj();
202                        }
203                        this._set("dropDownDefaultValue", val);
204                },
205
206                openDropDown: function(/*Function*/ callback){
207                        // rebuild drop down every time, so that constraints get copied (#6002)
208                        if(this.dropDown){
209                                this.dropDown.destroy();
210                        }
211                        var PopupProto = lang.isString(this.popupClass) ? lang.getObject(this.popupClass, false) : this.popupClass,
212                                textBox = this,
213                                value = this.get("value");
214                        this.dropDown = new PopupProto({
215                                onChange: function(value){
216                                        // this will cause InlineEditBox and other handlers to do stuff so make sure it's last
217                                        textBox.set('value', value, true);
218                                },
219                                id: this.id + "_popup",
220                                dir: textBox.dir,
221                                lang: textBox.lang,
222                                value: value,
223                                textDir: textBox.textDir,
224                                currentFocus: !this._isInvalidDate(value) ? value : this.dropDownDefaultValue,
225                                constraints: textBox.constraints,
226                                filterString: textBox.filterString, // for TimeTextBox, to filter times shown
227                                datePackage: textBox.params.datePackage,
228                                isDisabledDate: function(/*Date*/ date){
229                                        // summary:
230                                        //              disables dates outside of the min/max of the _DateTimeTextBox
231                                        return !textBox.rangeCheck(date, textBox.constraints);
232                                }
233                        });
234
235                        this.inherited(arguments);
236                },
237
238                _getDisplayedValueAttr: function(){
239                        return this.textbox.value;
240                },
241
242                _setDisplayedValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
243                        this._setValueAttr(this.parse(value, this.constraints), priorityChange, value);
244                }
245        });
246
247
248        /*=====
249         _DateTimeTextBox.__Constraints = declare([RangeBoundTextBox.__Constraints, locale.__FormatOptions], {
250                 // summary:
251                 //             Specifies both the rules on valid/invalid values (first/last date/time allowed),
252                 //             and also formatting options for how the date/time is displayed.
253                 // example:
254                 //             To restrict to dates within 2004, displayed in a long format like "December 25, 2005":
255                 //     |               {min:'2004-01-01',max:'2004-12-31', formatLength:'long'}
256         });
257         =====*/
258
259        return _DateTimeTextBox;
260});
Note: See TracBrowser for help on using the repository browser.