| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 | /*	Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.	Available via Academic Free License >= 2.1 OR the modified BSD license.	see: http://dojotoolkit.org/license for details*/if(!dojo._hasResource["dojox.mobile.app._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojox.mobile.app._FormWidget"] = true;dojo.provide("dojox.mobile.app._FormWidget");dojo.experimental("dojox.mobile.app._FormWidget");dojo.require("dojo.window");dojo.require("dijit._WidgetBase");dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {	// summary:	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,	//		which can be children of a <form> node or a `dojox.mobile.app.Form` widget.	//	// description:	//		Represents a single HTML element.	//		All these widgets should have these attributes just like native HTML input elements.	//		You can set them during widget construction or afterwards, via `dijit._WidgetBase.attr`.	//	//		They also share some common methods.	// name: String	//		Name used when submitting form; same as "name" attribute or plain HTML elements	name: "",	// alt: String	//		Corresponds to the native HTML <input> element's attribute.	alt: "",	// value: String	//		Corresponds to the native HTML <input> element's attribute.	value: "",	// type: String	//		Corresponds to the native HTML <input> element's attribute.	type: "text",	// disabled: Boolean	//		Should this widget respond to user input?	//		In markup, this is specified as "disabled='disabled'", or just "disabled".	disabled: false,	// intermediateChanges: Boolean	//		Fires onChange for each value change or only on demand	intermediateChanges: false,	// scrollOnFocus: Boolean	//		On focus, should this widget scroll into view?	scrollOnFocus: false,	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.	attributeMap: dojo.delegate(dijit._WidgetBase.prototype.attributeMap, {		value: "focusNode",		id: "focusNode",		alt: "focusNode",		title: "focusNode"	}),	postMixInProperties: function(){		// Setup name=foo string to be referenced from the template (but only if a name has been specified)		// Unfortunately we can't use attributeMap to set the name due to IE limitations, see #8660		// Regarding escaping, see heading "Attribute values" in		// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2		this.nameAttrSetting = this.name ? ('name="' + this.name.replace(/'/g, """) + '"') : '';		this.inherited(arguments);	},	postCreate: function(){		this.inherited(arguments);		this.connect(this.domNode, "onmousedown", "_onMouseDown");	},	_setDisabledAttr: function(/*Boolean*/ value){		this.disabled = value;		dojo.attr(this.focusNode, 'disabled', value);		if(this.valueNode){			dojo.attr(this.valueNode, 'disabled', value);		}	},	_onFocus: function(e){		if(this.scrollOnFocus){			dojo.window.scrollIntoView(this.domNode);		}		this.inherited(arguments);	},	isFocusable: function(){		// summary:		//		Tells if this widget is focusable or not.   Used internally by dijit.		// tags:		//		protected		return !this.disabled && !this.readOnly			&& this.focusNode && (dojo.style(this.domNode, "display") != "none");	},	focus: function(){		// summary:		//		Put focus on this widget		this.focusNode.focus();	},	compare: function(/*anything*/val1, /*anything*/val2){		// summary:		//		Compare 2 values (as returned by attr('value') for this widget).		// tags:		//		protected		if(typeof val1 == "number" && typeof val2 == "number"){			return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;		}else if(val1 > val2){			return 1;		}else if(val1 < val2){			return -1;		}else{			return 0;		}	},	onChange: function(newValue){		// summary:		//		Callback when this widget's value is changed.		// tags:		//		callback	},	// _onChangeActive: [private] Boolean	//		Indicates that changes to the value should call onChange() callback.	//		This is false during widget initialization, to avoid calling onChange()	//		when the initial value is set.	_onChangeActive: false,	_handleOnChange: function(/*anything*/ newValue, /* Boolean? */ priorityChange){		// summary:		//		Called when the value of the widget is set.  Calls onChange() if appropriate		// newValue:		//		the new value		// priorityChange:		//		For a slider, for example, dragging the slider is priorityChange==false,		//		but on mouse up, it's priorityChange==true.  If intermediateChanges==true,		//		onChange is only called form priorityChange=true events.		// tags:		//		private		this._lastValue = newValue;		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){			// this block executes not for a change, but during initialization,			// and is used to store away the original value (or for ToggleButton, the original checked state)			this._resetValue = this._lastValueReported = newValue;		}		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&			((typeof newValue != typeof this._lastValueReported) ||				this.compare(newValue, this._lastValueReported) != 0)){			this._lastValueReported = newValue;			if(this._onChangeActive){				if(this._onChangeHandle){					clearTimeout(this._onChangeHandle);				}				// setTimout allows hidden value processing to run and				// also the onChange handler can safely adjust focus, etc				this._onChangeHandle = setTimeout(dojo.hitch(this,					function(){						this._onChangeHandle = null;						this.onChange(newValue);					}), 0); // try to collapse multiple onChange's fired faster than can be processed			}		}	},	create: function(){		// Overrides _Widget.create()		this.inherited(arguments);		this._onChangeActive = true;	},	destroy: function(){		if(this._onChangeHandle){ // destroy called before last onChange has fired			clearTimeout(this._onChangeHandle);			this.onChange(this._lastValueReported);		}		this.inherited(arguments);	},	_onMouseDown: function(e){		// If user clicks on the button, even if the mouse is released outside of it,		// this button should get focus (to mimics native browser buttons).		// This is also needed on chrome because otherwise buttons won't get focus at all,		// which leads to bizarre focus restore on Dialog close etc.		if(this.isFocusable()){			// Set a global event to handle mouseup, so it fires properly			// even if the cursor leaves this.domNode before the mouse up event.			var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){				if(this.isFocusable()){					this.focus();				}				this.disconnect(mouseUpConnector);			});		}	},	selectInputText: function(/*DomNode*/element, /*Number?*/ start, /*Number?*/ stop){		// summary:		//		Select text in the input element argument, from start (default 0), to stop (default end).		// TODO: use functions in _editor/selection.js?		var _window = dojo.global;		var _document = dojo.doc;		element = dojo.byId(element);		if(isNaN(start)){ start = 0; }		if(isNaN(stop)){ stop = element.value ? element.value.length : 0; }		dijit.focus(element);		if(_window["getSelection"] && element.setSelectionRange){			element.setSelectionRange(start, stop);		}	}});dojo.declare("dojox.mobile.app._FormValueWidget", dojox.mobile.app._FormWidget,{	// summary:	//		Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.	// description:	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,	//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)	//		works as expected.	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared	// directly in the template as read by the parser in order to function. IE is known to specifically	// require the 'name' attribute at element creation time.   See #8484, #8660.	// TODO: unclear what that {value: ""} is for; FormWidget.attributeMap copies value to focusNode,	// so maybe {value: ""} is so the value *doesn't* get copied to focusNode?	// Seems like we really want value removed from attributeMap altogether	// (although there's no easy way to do that now)	// readOnly: Boolean	//		Should this widget respond to user input?	//		In markup, this is specified as "readOnly".	//		Similar to disabled except readOnly form values are submitted.	readOnly: false,	attributeMap: dojo.delegate(dojox.mobile.app._FormWidget.prototype.attributeMap, {		value: "",		readOnly: "focusNode"	}),	_setReadOnlyAttr: function(/*Boolean*/ value){		this.readOnly = value;		dojo.attr(this.focusNode, 'readOnly', value);	},	postCreate: function(){		this.inherited(arguments);		// Update our reset value if it hasn't yet been set (because this.set()		// is only called when there *is* a value)		if(this._resetValue === undefined){			this._resetValue = this.value;		}	},	_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){		// summary:		//		Hook so attr('value', value) works.		// description:		//		Sets the value of the widget.		//		If the value has changed, then fire onChange event, unless priorityChange		//		is specified as null (or false?)		this.value = newValue;		this._handleOnChange(newValue, priorityChange);	},	_getValueAttr: function(){		// summary:		//		Hook so attr('value') works.		return this._lastValue;	},	undo: function(){		// summary:		//		Restore the value to the last value passed to onChange		this._setValueAttr(this._lastValueReported, false);	},	reset: function(){		// summary:		//		Reset the widget's value to what it was at initialization time		this._hasBeenBlurred = false;		this._setValueAttr(this._resetValue, true);	}});}
 |