]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dijit/form/_FormWidget.js
Comment class stub
[eow] / static / dojo-release-1.1.1 / dijit / form / _FormWidget.js
1 if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.form._FormWidget"] = true;
3 dojo.provide("dijit.form._FormWidget");
4
5 dojo.require("dijit._Widget");
6 dojo.require("dijit._Templated");
7
8 dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated],
9 {
10         /*
11         Summary:
12                 _FormWidget's correspond to native HTML elements such as <checkbox> or <button>.
13                 Each _FormWidget represents a single HTML element.
14
15                 All these widgets should have these attributes just like native HTML input elements.
16                 You can set them during widget construction.
17
18                 They also share some common methods.
19         */
20
21         // baseClass: String
22         //              Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget
23         //              (ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused")
24         //              See _setStateClass().
25         baseClass: "",
26
27         // name: String
28         //              Name used when submitting form; same as "name" attribute or plain HTML elements
29         name: "",
30
31         // alt: String
32         //              Corresponds to the native HTML <input> element's attribute.
33         alt: "",
34
35         // value: String
36         //              Corresponds to the native HTML <input> element's attribute.
37         value: "",
38
39         // type: String
40         //              Corresponds to the native HTML <input> element's attribute.
41         type: "text",
42
43         // tabIndex: Integer
44         //              Order fields are traversed when user hits the tab key
45         tabIndex: "0",
46
47         // disabled: Boolean
48         //              Should this widget respond to user input?
49         //              In markup, this is specified as "disabled='disabled'", or just "disabled".
50         disabled: false,
51
52         // readOnly: Boolean
53         //              Should this widget respond to user input?
54         //              In markup, this is specified as "readOnly".
55         //              Similar to disabled except readOnly form values are submitted
56         readOnly: false,
57
58         // intermediateChanges: Boolean
59         //              Fires onChange for each value change or only on demand
60         intermediateChanges: false,
61
62         // These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
63         // Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
64         // directly in the template as read by the parser in order to function. IE is known to specifically 
65         // require the 'name' attribute at element creation time.
66         attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
67                 {value:"focusNode", disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}),
68
69         setAttribute: function(/*String*/ attr, /*anything*/ value){
70                 this.inherited(arguments);
71                 switch(attr){
72                         case "disabled":
73                                 var tabIndexNode = this[this.attributeMap['tabIndex']||'domNode'];
74                                 if(value){
75                                         //reset those, because after the domNode is disabled, we can no longer receive
76                                         //mouse related events, see #4200
77                                         this._hovering = false;
78                                         this._active = false;
79                                         // remove the tabIndex, especially for FF
80                                         tabIndexNode.removeAttribute('tabIndex');
81                                 }else{
82                                         tabIndexNode.setAttribute('tabIndex', this.tabIndex);
83                                 }
84                                 dijit.setWaiState(this[this.attributeMap['disabled']||'domNode'], "disabled", value);
85                                 this._setStateClass();
86                 }
87         },
88
89         setDisabled: function(/*Boolean*/ disabled){
90                 // summary:
91                 //              Set disabled state of widget (Deprecated).
92                 dojo.deprecated("setDisabled("+disabled+") is deprecated. Use setAttribute('disabled',"+disabled+") instead.", "", "2.0");
93                 this.setAttribute('disabled', disabled);
94         },
95
96
97         _onMouse : function(/*Event*/ event){
98                 // summary:
99                 //      Sets _hovering, _active, and stateModifier properties depending on mouse state,
100                 //      then calls setStateClass() to set appropriate CSS classes for this.domNode.
101                 //
102                 //      To get a different CSS class for hover, send onmouseover and onmouseout events to this method.
103                 //      To get a different CSS class while mouse button is depressed, send onmousedown to this method.
104
105                 var mouseNode = event.currentTarget;
106                 if(mouseNode && mouseNode.getAttribute){
107                         this.stateModifier = mouseNode.getAttribute("stateModifier") || "";
108                 }
109
110                 if(!this.disabled){
111                         switch(event.type){
112                                 case "mouseenter":      
113                                 case "mouseover":
114                                         this._hovering = true;
115                                         this._active = this._mouseDown;
116                                         break;
117
118                                 case "mouseout":
119                                 case "mouseleave":
120                                         this._hovering = false;
121                                         this._active = false;
122                                         break;
123
124                                 case "mousedown" :
125                                         this._active = true;
126                                         this._mouseDown = true;
127                                         // set a global event to handle mouseup, so it fires properly
128                                         //      even if the cursor leaves the button
129                                         var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){
130                                                 this._active = false;
131                                                 this._mouseDown = false;
132                                                 this._setStateClass();
133                                                 this.disconnect(mouseUpConnector);
134                                         });
135                                         if(this.isFocusable()){ this.focus(); }
136                                         break;
137                         }
138                         this._setStateClass();
139                 }
140         },
141
142         isFocusable: function(){
143                 return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
144         },
145
146         focus: function(){
147                 setTimeout(dojo.hitch(this, dijit.focus, this.focusNode), 0); // cannot call focus() from an event handler directly
148         },
149
150         _setStateClass: function(){
151                 // summary
152                 //      Update the visual state of the widget by setting the css classes on this.domNode
153                 //  (or this.stateNode if defined) by combining this.baseClass with
154                 //      various suffixes that represent the current widget state(s).
155                 //
156                 //      In the case where a widget has multiple
157                 //      states, it sets the class based on all possible
158                 //  combinations.  For example, an invalid form widget that is being hovered
159                 //      will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
160                 //
161                 //      For complex widgets with multiple regions, there can be various hover/active states,
162                 //      such as "Hover" or "CloseButtonHover" (for tab buttons).
163                 //      This is controlled by a stateModifier="CloseButton" attribute on the close button node.
164                 //
165                 //      The widget may have one or more of the following states, determined
166                 //      by this.state, this.checked, this.valid, and this.selected:
167                 //              Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
168                 //              Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
169                 //              Selected - ex: currently selected tab will have this.selected==true
170                 //
171                 //      In addition, it may have one or more of the following states,
172                 //      based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
173                 //              Disabled        - if the widget is disabled
174                 //              Active          - if the mouse (or space/enter key?) is being pressed down
175                 //              Focused         - if the widget has focus
176                 //              Hover           - if the mouse is over the widget
177
178                 // Get original (non state related, non baseClass related) class specified in template
179                 if(!("staticClass" in this)){
180                         this.staticClass = (this.stateNode||this.domNode).className;
181                 }
182
183                 // Compute new set of classes
184                 var classes = [ this.baseClass ];
185
186                 function multiply(modifier){
187                         classes=classes.concat(dojo.map(classes, function(c){ return c+modifier; }), "dijit"+modifier);
188                 }
189
190                 if(this.checked){
191                         multiply("Checked");
192                 }
193                 if(this.state){
194                         multiply(this.state);
195                 }
196                 if(this.selected){
197                         multiply("Selected");
198                 }
199
200                 if(this.disabled){
201                         multiply("Disabled");
202                 }else if(this.readOnly){
203                         multiply("ReadOnly");
204                 }else if(this._active){
205                         multiply(this.stateModifier+"Active");
206                 }else{
207                         if(this._focused){
208                                 multiply("Focused");
209                         }
210                         if(this._hovering){
211                                 multiply(this.stateModifier+"Hover");
212                         }
213                 }
214
215                 (this.stateNode || this.domNode).className = this.staticClass + " " + classes.join(" ");
216         },
217
218         onChange: function(newValue){
219                 // summary: callback when value is changed
220         },
221
222         _onChangeMonitor: 'value',
223         _onChangeActive: false,
224
225         _handleOnChange: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
226                 // summary: set the value of the widget.
227                 this._lastValue = newValue;
228                 if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
229                         this._resetValue = this._lastValueReported = newValue;
230                 }
231                 if((this.intermediateChanges || priorityChange || priorityChange === undefined) && 
232                         ((newValue && newValue.toString)?newValue.toString():newValue) !== ((this._lastValueReported && this._lastValueReported.toString)?this._lastValueReported.toString():this._lastValueReported)){
233                         this._lastValueReported = newValue;
234                         if(this._onChangeActive){ this.onChange(newValue); }
235                 }
236         },
237
238         reset: function(){
239                 this._hasBeenBlurred = false;
240                 if(this.setValue && !this._getValueDeprecated){
241                         this.setValue(this._resetValue, true);
242                 }else if(this._onChangeMonitor){
243                         this.setAttribute(this._onChangeMonitor, (this._resetValue !== undefined && this._resetValue !== null)? this._resetValue : '');
244                 }
245         },
246
247         create: function(){
248                 this.inherited(arguments);
249                 this._onChangeActive = true;
250                 this._setStateClass();
251         },
252         
253         destroy: function(){
254                 if(this._layoutHackHandle){
255                         clearTimeout(this._layoutHackHandle);
256                 }
257                 this.inherited(arguments);
258         },
259
260         setValue: function(/*String*/ value){
261                 dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use setAttribute('value',"+value+") instead.", "", "2.0");
262                 this.setAttribute('value', value);
263         },
264
265         _getValueDeprecated: true, // Form uses this, remove when getValue is removed
266         getValue: function(){
267                 dojo.deprecated("dijit.form._FormWidget:getValue() is deprecated.  Use widget.value instead.", "", "2.0");
268                 return this.value;
269         },
270
271         _layoutHack: function(){
272                 // summary: work around table sizing bugs on FF2 by forcing redraw
273                 if(dojo.isFF == 2){
274                         var node=this.domNode;
275                         var old = node.style.opacity;
276                         node.style.opacity = "0.999";
277                         this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){
278                                 this._layoutHackHandle = null;
279                                 node.style.opacity = old;
280                         }), 0);
281                 }
282         }
283 });
284
285 dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
286 {
287         /*
288         Summary:
289                 _FormValueWidget's correspond to native HTML elements such as <input> or <select> that have user changeable values.
290                 Each _ValueWidget represents a single input value, and has a (possibly hidden) <input> element,
291                 to which it serializes its input value, so that form submission (either normal submission or via FormBind?)
292                 works as expected.
293         */
294
295         attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap),
296                 {value:""}),
297
298         postCreate: function(){
299                 this.setValue(this.value, null);
300         },
301
302         setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
303                 // summary: set the value of the widget.
304                 this.value = newValue;
305                 this._handleOnChange(newValue, priorityChange);
306         },
307
308         _getValueDeprecated: false, // remove when _FormWidget:getValue is removed
309         getValue: function(){
310                 // summary: get the value of the widget.
311                 return this._lastValue;
312         },
313
314         undo: function(){
315                 // summary: restore the value to the last value passed to onChange
316                 this.setValue(this._lastValueReported, false);
317         },
318
319         _valueChanged: function(){
320                 var v = this.getValue();
321                 var lv = this._lastValueReported;
322                 // Equality comparison of objects such as dates are done by reference so
323                 // two distinct objects are != even if they have the same data. So use
324                 // toStrings in case the values are objects.
325                 return ((v !== null && (v !== undefined) && v.toString)?v.toString():'') !== ((lv !== null && (lv !== undefined) && lv.toString)?lv.toString():'');
326         },
327
328         _onKeyPress: function(e){
329                 if(e.keyCode == dojo.keys.ESCAPE && !e.shiftKey && !e.ctrlKey && !e.altKey){
330                         if(this._valueChanged()){
331                                 this.undo();
332                                 dojo.stopEvent(e);
333                                 return false;
334                         }
335                 }
336                 return true;
337         }
338 });
339
340 }