summaryrefslogtreecommitdiff
path: root/lib/dijit/form/_FormWidgetMixin.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/form/_FormWidgetMixin.js.uncompressed.js')
-rw-r--r--lib/dijit/form/_FormWidgetMixin.js.uncompressed.js227
1 files changed, 227 insertions, 0 deletions
diff --git a/lib/dijit/form/_FormWidgetMixin.js.uncompressed.js b/lib/dijit/form/_FormWidgetMixin.js.uncompressed.js
new file mode 100644
index 000000000..7900b6e28
--- /dev/null
+++ b/lib/dijit/form/_FormWidgetMixin.js.uncompressed.js
@@ -0,0 +1,227 @@
+define("dijit/form/_FormWidgetMixin", [
+ "dojo/_base/array", // array.forEach
+ "dojo/_base/declare", // declare
+ "dojo/dom-attr", // domAttr.set
+ "dojo/dom-style", // domStyle.get
+ "dojo/_base/lang", // lang.hitch lang.isArray
+ "dojo/mouse", // mouse.isLeft
+ "dojo/_base/sniff", // has("webkit")
+ "dojo/_base/window", // win.body
+ "dojo/window", // winUtils.scrollIntoView
+ "../a11y" // a11y.hasDefaultTabStop
+], function(array, declare, domAttr, domStyle, lang, mouse, has, win, winUtils, a11y){
+
+// module:
+// dijit/form/_FormWidgetMixin
+// summary:
+// Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+// which can be children of a <form> node or a `dijit.form.Form` widget.
+
+return declare("dijit.form._FormWidgetMixin", null, {
+ // summary:
+ // Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
+ // which can be children of a <form> node or a `dijit.form.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._Widget.attr`.
+ //
+ // They also share some common methods.
+
+ // name: [const] 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: [const] String
+ // Corresponds to the native HTML <input> element's attribute.
+ type: "text",
+
+ // tabIndex: Integer
+ // Order fields are traversed when user hits the tab key
+ tabIndex: "0",
+ _setTabIndexAttr: "focusNode", // force copy even when tabIndex default value, needed since Button is <span>
+
+ // 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: true,
+
+ // Override _WidgetBase mapping id to this.domNode, needs to be on focusNode so <label> etc.
+ // works with screen reader
+ _setIdAttr: "focusNode",
+
+ _setDisabledAttr: function(/*Boolean*/ value){
+ this._set("disabled", value);
+ domAttr.set(this.focusNode, 'disabled', value);
+ if(this.valueNode){
+ domAttr.set(this.valueNode, 'disabled', value);
+ }
+ this.focusNode.setAttribute("aria-disabled", value ? "true" : "false");
+
+ if(value){
+ // reset these, because after the domNode is disabled, we can no longer receive
+ // mouse related events, see #4200
+ this._set("hovering", false);
+ this._set("active", false);
+
+ // clear tab stop(s) on this widget's focusable node(s) (ComboBox has two focusable nodes)
+ var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex :
+ ("_setTabIndexAttr" in this) ? this._setTabIndexAttr : "focusNode";
+ array.forEach(lang.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
+ var node = this[attachPointName];
+ // complex code because tabIndex=-1 on a <div> doesn't work on FF
+ if(has("webkit") || a11y.hasDefaultTabStop(node)){ // see #11064 about webkit bug
+ node.setAttribute('tabIndex', "-1");
+ }else{
+ node.removeAttribute('tabIndex');
+ }
+ }, this);
+ }else{
+ if(this.tabIndex != ""){
+ this.set('tabIndex', this.tabIndex);
+ }
+ }
+ },
+
+ _onFocus: function(/*String*/ by){
+ // If user clicks on the widget, even if the mouse is released outside of it,
+ // this widget's focusNode should get focus (to mimic native browser hehavior).
+ // Browsers often need help to make sure the focus via mouse actually gets to the focusNode.
+ if(by == "mouse" && this.isFocusable()){
+ // IE exhibits strange scrolling behavior when refocusing a node so only do it when !focused.
+ var focusConnector = this.connect(this.focusNode, "onfocus", function(){
+ this.disconnect(mouseUpConnector);
+ this.disconnect(focusConnector);
+ });
+ // 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(win.body(), "onmouseup", function(){
+ this.disconnect(mouseUpConnector);
+ this.disconnect(focusConnector);
+ // if here, then the mousedown did not focus the focusNode as the default action
+ if(this.focused){
+ this.focus();
+ }
+ });
+ }
+ if(this.scrollOnFocus){
+ this.defer(function(){ winUtils.scrollIntoView(this.domNode); }); // without defer, the input caret position can change on mouse click
+ }
+ this.inherited(arguments);
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Tells if this widget is focusable or not. Used internally by dijit.
+ // tags:
+ // protected
+ return !this.disabled && this.focusNode && (domStyle.get(this.domNode, "display") != "none");
+ },
+
+ focus: function(){
+ // summary:
+ // Put focus on this widget
+ if(!this.disabled && this.focusNode.focus){
+ try{ this.focusNode.focus(); }catch(e){}/*squelch errors from hidden nodes*/
+ }
+ },
+
+ compare: function(/*anything*/ val1, /*anything*/ val2){
+ // summary:
+ // Compare 2 values (as returned by get('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==false,
+ // onChange is only called form priorityChange=true events.
+ // tags:
+ // private
+ 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;
+ }
+ this._pendingOnChange = this._pendingOnChange
+ || (typeof newValue != typeof this._lastValueReported)
+ || (this.compare(newValue, this._lastValueReported) != 0);
+ if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
+ this._lastValueReported = newValue;
+ this._pendingOnChange = false;
+ if(this._onChangeActive){
+ if(this._onChangeHandle){
+ this._onChangeHandle.remove();
+ }
+ // defer allows hidden value processing to run and
+ // also the onChange handler can safely adjust focus, etc
+ this._onChangeHandle = this.defer(
+ function(){
+ this._onChangeHandle = null;
+ this.onChange(newValue);
+ }); // 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
+ this._onChangeHandle.remove();
+ this.onChange(this._lastValueReported);
+ }
+ this.inherited(arguments);
+ }
+});
+
+});