summaryrefslogtreecommitdiff
path: root/lib/dijit/form/_FormMixin.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dijit/form/_FormMixin.js')
-rw-r--r--lib/dijit/form/_FormMixin.js463
1 files changed, 2 insertions, 461 deletions
diff --git a/lib/dijit/form/_FormMixin.js b/lib/dijit/form/_FormMixin.js
index e42702d31..770ec2471 100644
--- a/lib/dijit/form/_FormMixin.js
+++ b/lib/dijit/form/_FormMixin.js
@@ -1,461 +1,2 @@
-/*
- Copyright (c) 2004-2011, 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["dijit.form._FormMixin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
-dojo._hasResource["dijit.form._FormMixin"] = true;
-dojo.provide("dijit.form._FormMixin");
-dojo.require("dojo.window");
-
-
-dojo.declare("dijit.form._FormMixin", null, {
- // summary:
- // Mixin for containers of form widgets (i.e. widgets that represent a single value
- // and can be children of a <form> node or dijit.form.Form widget)
- // description:
- // Can extract all the form widgets
- // values and combine them into a single javascript object, or alternately
- // take such an object and set the values for all the contained
- // form widgets
-
-/*=====
- // value: Object
- // Name/value hash for each child widget with a name and value.
- // Child widgets without names are not part of the hash.
- //
- // If there are multiple child widgets w/the same name, value is an array,
- // unless they are radio buttons in which case value is a scalar (since only
- // one radio button can be checked at a time).
- //
- // If a child widget's name is a dot separated list (like a.b.c.d), it's a nested structure.
- //
- // Example:
- // | { name: "John Smith", interests: ["sports", "movies"] }
-=====*/
-
- // state: [readonly] String
- // Will be "Error" if one or more of the child widgets has an invalid value,
- // "Incomplete" if not all of the required child widgets are filled in. Otherwise, "",
- // which indicates that the form is ready to be submitted.
- state: "",
-
- // TODO:
- // * Repeater
- // * better handling for arrays. Often form elements have names with [] like
- // * people[3].sex (for a list of people [{name: Bill, sex: M}, ...])
- //
- //
-
- reset: function(){
- dojo.forEach(this.getDescendants(), function(widget){
- if(widget.reset){
- widget.reset();
- }
- });
- },
-
- validate: function(){
- // summary:
- // returns if the form is valid - same as isValid - but
- // provides a few additional (ui-specific) features.
- // 1 - it will highlight any sub-widgets that are not
- // valid
- // 2 - it will call focus() on the first invalid
- // sub-widget
- var didFocus = false;
- return dojo.every(dojo.map(this.getDescendants(), function(widget){
- // Need to set this so that "required" widgets get their
- // state set.
- widget._hasBeenBlurred = true;
- var valid = widget.disabled || !widget.validate || widget.validate();
- if(!valid && !didFocus){
- // Set focus of the first non-valid widget
- dojo.window.scrollIntoView(widget.containerNode || widget.domNode);
- widget.focus();
- didFocus = true;
- }
- return valid;
- }), function(item){ return item; });
- },
-
- setValues: function(val){
- dojo.deprecated(this.declaredClass+"::setValues() is deprecated. Use set('value', val) instead.", "", "2.0");
- return this.set('value', val);
- },
- _setValueAttr: function(/*Object*/ obj){
- // summary:
- // Fill in form values from according to an Object (in the format returned by get('value'))
-
- // generate map from name --> [list of widgets with that name]
- var map = { };
- dojo.forEach(this.getDescendants(), function(widget){
- if(!widget.name){ return; }
- var entry = map[widget.name] || (map[widget.name] = [] );
- entry.push(widget);
- });
-
- for(var name in map){
- if(!map.hasOwnProperty(name)){
- continue;
- }
- var widgets = map[name], // array of widgets w/this name
- values = dojo.getObject(name, false, obj); // list of values for those widgets
-
- if(values === undefined){
- continue;
- }
- if(!dojo.isArray(values)){
- values = [ values ];
- }
- if(typeof widgets[0].checked == 'boolean'){
- // for checkbox/radio, values is a list of which widgets should be checked
- dojo.forEach(widgets, function(w, i){
- w.set('value', dojo.indexOf(values, w.value) != -1);
- });
- }else if(widgets[0].multiple){
- // it takes an array (e.g. multi-select)
- widgets[0].set('value', values);
- }else{
- // otherwise, values is a list of values to be assigned sequentially to each widget
- dojo.forEach(widgets, function(w, i){
- w.set('value', values[i]);
- });
- }
- }
-
- /***
- * TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets)
-
- dojo.forEach(this.containerNode.elements, function(element){
- if(element.name == ''){return}; // like "continue"
- var namePath = element.name.split(".");
- var myObj=obj;
- var name=namePath[namePath.length-1];
- for(var j=1,len2=namePath.length;j<len2;++j){
- var p=namePath[j - 1];
- // repeater support block
- var nameA=p.split("[");
- if(nameA.length > 1){
- if(typeof(myObj[nameA[0]]) == "undefined"){
- myObj[nameA[0]]=[ ];
- } // if
-
- nameIndex=parseInt(nameA[1]);
- if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){
- myObj[nameA[0]][nameIndex] = { };
- }
- myObj=myObj[nameA[0]][nameIndex];
- continue;
- } // repeater support ends
-
- if(typeof(myObj[p]) == "undefined"){
- myObj=undefined;
- break;
- };
- myObj=myObj[p];
- }
-
- if(typeof(myObj) == "undefined"){
- return; // like "continue"
- }
- if(typeof(myObj[name]) == "undefined" && this.ignoreNullValues){
- return; // like "continue"
- }
-
- // TODO: widget values (just call set('value', ...) on the widget)
-
- // TODO: maybe should call dojo.getNodeProp() instead
- switch(element.type){
- case "checkbox":
- element.checked = (name in myObj) &&
- dojo.some(myObj[name], function(val){ return val == element.value; });
- break;
- case "radio":
- element.checked = (name in myObj) && myObj[name] == element.value;
- break;
- case "select-multiple":
- element.selectedIndex=-1;
- dojo.forEach(element.options, function(option){
- option.selected = dojo.some(myObj[name], function(val){ return option.value == val; });
- });
- break;
- case "select-one":
- element.selectedIndex="0";
- dojo.forEach(element.options, function(option){
- option.selected = option.value == myObj[name];
- });
- break;
- case "hidden":
- case "text":
- case "textarea":
- case "password":
- element.value = myObj[name] || "";
- break;
- }
- });
- */
-
- // Note: no need to call this._set("value", ...) as the child updates will trigger onChange events
- // which I am monitoring.
- },
-
- getValues: function(){
- dojo.deprecated(this.declaredClass+"::getValues() is deprecated. Use get('value') instead.", "", "2.0");
- return this.get('value');
- },
- _getValueAttr: function(){
- // summary:
- // Returns Object representing form values. See description of `value` for details.
- // description:
-
- // The value is updated into this.value every time a child has an onChange event,
- // so in the common case this function could just return this.value. However,
- // that wouldn't work when:
- //
- // 1. User presses return key to submit a form. That doesn't fire an onchange event,
- // and even if it did it would come too late due to the setTimout(..., 0) in _handleOnChange()
- //
- // 2. app for some reason calls this.get("value") while the user is typing into a
- // form field. Not sure if that case needs to be supported or not.
-
- // get widget values
- var obj = { };
- dojo.forEach(this.getDescendants(), function(widget){
- var name = widget.name;
- if(!name || widget.disabled){ return; }
-
- // Single value widget (checkbox, radio, or plain <input> type widget)
- var value = widget.get('value');
-
- // Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays
- if(typeof widget.checked == 'boolean'){
- if(/Radio/.test(widget.declaredClass)){
- // radio button
- if(value !== false){
- dojo.setObject(name, value, obj);
- }else{
- // give radio widgets a default of null
- value = dojo.getObject(name, false, obj);
- if(value === undefined){
- dojo.setObject(name, null, obj);
- }
- }
- }else{
- // checkbox/toggle button
- var ary=dojo.getObject(name, false, obj);
- if(!ary){
- ary=[];
- dojo.setObject(name, ary, obj);
- }
- if(value !== false){
- ary.push(value);
- }
- }
- }else{
- var prev=dojo.getObject(name, false, obj);
- if(typeof prev != "undefined"){
- if(dojo.isArray(prev)){
- prev.push(value);
- }else{
- dojo.setObject(name, [prev, value], obj);
- }
- }else{
- // unique name
- dojo.setObject(name, value, obj);
- }
- }
- });
-
- /***
- * code for plain input boxes (see also dojo.formToObject, can we use that instead of this code?
- * but it doesn't understand [] notation, presumably)
- var obj = { };
- dojo.forEach(this.containerNode.elements, function(elm){
- if(!elm.name) {
- return; // like "continue"
- }
- var namePath = elm.name.split(".");
- var myObj=obj;
- var name=namePath[namePath.length-1];
- for(var j=1,len2=namePath.length;j<len2;++j){
- var nameIndex = null;
- var p=namePath[j - 1];
- var nameA=p.split("[");
- if(nameA.length > 1){
- if(typeof(myObj[nameA[0]]) == "undefined"){
- myObj[nameA[0]]=[ ];
- } // if
- nameIndex=parseInt(nameA[1]);
- if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){
- myObj[nameA[0]][nameIndex] = { };
- }
- } else if(typeof(myObj[nameA[0]]) == "undefined"){
- myObj[nameA[0]] = { }
- } // if
-
- if(nameA.length == 1){
- myObj=myObj[nameA[0]];
- } else{
- myObj=myObj[nameA[0]][nameIndex];
- } // if
- } // for
-
- if((elm.type != "select-multiple" && elm.type != "checkbox" && elm.type != "radio") || (elm.type == "radio" && elm.checked)){
- if(name == name.split("[")[0]){
- myObj[name]=elm.value;
- } else{
- // can not set value when there is no name
- }
- } else if(elm.type == "checkbox" && elm.checked){
- if(typeof(myObj[name]) == 'undefined'){
- myObj[name]=[ ];
- }
- myObj[name].push(elm.value);
- } else if(elm.type == "select-multiple"){
- if(typeof(myObj[name]) == 'undefined'){
- myObj[name]=[ ];
- }
- for(var jdx=0,len3=elm.options.length; jdx<len3; ++jdx){
- if(elm.options[jdx].selected){
- myObj[name].push(elm.options[jdx].value);
- }
- }
- } // if
- name=undefined;
- }); // forEach
- ***/
- return obj;
- },
-
- isValid: function(){
- // summary:
- // Returns true if all of the widgets are valid.
- // Deprecated, will be removed in 2.0. Use get("state") instead.
-
- return this.state == "";
- },
-
- onValidStateChange: function(isValid){
- // summary:
- // Stub function to connect to if you want to do something
- // (like disable/enable a submit button) when the valid
- // state changes on the form as a whole.
- //
- // Deprecated. Will be removed in 2.0. Use watch("state", ...) instead.
- },
-
- _getState: function(){
- // summary:
- // Compute what this.state should be based on state of children
- var states = dojo.map(this._descendants, function(w){
- return w.get("state") || "";
- });
-
- return dojo.indexOf(states, "Error") >= 0 ? "Error" :
- dojo.indexOf(states, "Incomplete") >= 0 ? "Incomplete" : "";
- },
-
- disconnectChildren: function(){
- // summary:
- // Remove connections to monitor changes to children's value, error state, and disabled state,
- // in order to update Form.value and Form.state.
- dojo.forEach(this._childConnections || [], dojo.hitch(this, "disconnect"));
- dojo.forEach(this._childWatches || [], function(w){ w.unwatch(); });
- },
-
- connectChildren: function(/*Boolean*/ inStartup){
- // summary:
- // Setup connections to monitor changes to children's value, error state, and disabled state,
- // in order to update Form.value and Form.state.
- //
- // You can call this function directly, ex. in the event that you
- // programmatically add a widget to the form *after* the form has been
- // initialized.
-
- var _this = this;
-
- // Remove old connections, if any
- this.disconnectChildren();
-
- this._descendants = this.getDescendants();
-
- // (Re)set this.value and this.state. Send watch() notifications but not on startup.
- var set = inStartup ? function(name, val){ _this[name] = val; } : dojo.hitch(this, "_set");
- set("value", this.get("value"));
- set("state", this._getState());
-
- // Monitor changes to error state and disabled state in order to update
- // Form.state
- var conns = (this._childConnections = []),
- watches = (this._childWatches = []);
- dojo.forEach(dojo.filter(this._descendants,
- function(item){ return item.validate; }
- ),
- function(widget){
- // We are interested in whenever the widget changes validity state - or
- // whenever the disabled attribute on that widget is changed.
- dojo.forEach(["state", "disabled"], function(attr){
- watches.push(widget.watch(attr, function(attr, oldVal, newVal){
- _this.set("state", _this._getState());
- }));
- });
- });
-
- // And monitor calls to child.onChange so we can update this.value
- var onChange = function(){
- // summary:
- // Called when child's value or disabled state changes
-
- // Use setTimeout() to collapse value changes in multiple children into a single
- // update to my value. Multiple updates will occur on:
- // 1. Form.set()
- // 2. Form.reset()
- // 3. user selecting a radio button (which will de-select another radio button,
- // causing two onChange events)
- if(_this._onChangeDelayTimer){
- clearTimeout(_this._onChangeDelayTimer);
- }
- _this._onChangeDelayTimer = setTimeout(function(){
- delete _this._onChangeDelayTimer;
- _this._set("value", _this.get("value"));
- }, 10);
- };
- dojo.forEach(
- dojo.filter(this._descendants, function(item){ return item.onChange; } ),
- function(widget){
- // When a child widget's value changes,
- // the efficient thing to do is to just update that one attribute in this.value,
- // but that gets a little complicated when a checkbox is checked/unchecked
- // since this.value["checkboxName"] contains an array of all the checkboxes w/the same name.
- // Doing simple thing for now.
- conns.push(_this.connect(widget, "onChange", onChange));
-
- // Disabling/enabling a child widget should remove it's value from this.value.
- // Again, this code could be more efficient, doing simple thing for now.
- watches.push(widget.watch("disabled", onChange));
- }
- );
- },
-
- startup: function(){
- this.inherited(arguments);
-
- // Initialize value and valid/invalid state tracking. Needs to be done in startup()
- // so that children are initialized.
- this.connectChildren(true);
-
- // Make state change call onValidStateChange(), will be removed in 2.0
- this.watch("state", function(attr, oldVal, newVal){ this.onValidStateChange(newVal == ""); });
- },
-
- destroy: function(){
- this.disconnectChildren();
- this.inherited(arguments);
- }
-
- });
-
-}
+//>>built
+define("dijit/form/_FormMixin",["dojo/_base/array","dojo/_base/declare","dojo/_base/kernel","dojo/_base/lang","dojo/window"],function(_1,_2,_3,_4,_5){return _2("dijit.form._FormMixin",null,{state:"",_getDescendantFormWidgets:function(_6){var _7=[];_1.forEach(_6||this.getChildren(),function(_8){if("value" in _8){_7.push(_8);}else{_7=_7.concat(this._getDescendantFormWidgets(_8.getChildren()));}},this);return _7;},reset:function(){_1.forEach(this._getDescendantFormWidgets(),function(_9){if(_9.reset){_9.reset();}});},validate:function(){var _a=false;return _1.every(_1.map(this._getDescendantFormWidgets(),function(_b){_b._hasBeenBlurred=true;var _c=_b.disabled||!_b.validate||_b.validate();if(!_c&&!_a){_5.scrollIntoView(_b.containerNode||_b.domNode);_b.focus();_a=true;}return _c;}),function(_d){return _d;});},setValues:function(_e){_3.deprecated(this.declaredClass+"::setValues() is deprecated. Use set('value', val) instead.","","2.0");return this.set("value",_e);},_setValueAttr:function(_f){var map={};_1.forEach(this._getDescendantFormWidgets(),function(_10){if(!_10.name){return;}var _11=map[_10.name]||(map[_10.name]=[]);_11.push(_10);});for(var _12 in map){if(!map.hasOwnProperty(_12)){continue;}var _13=map[_12],_14=_4.getObject(_12,false,_f);if(_14===undefined){continue;}if(!_4.isArray(_14)){_14=[_14];}if(typeof _13[0].checked=="boolean"){_1.forEach(_13,function(w){w.set("value",_1.indexOf(_14,w.value)!=-1);});}else{if(_13[0].multiple){_13[0].set("value",_14);}else{_1.forEach(_13,function(w,i){w.set("value",_14[i]);});}}}},getValues:function(){_3.deprecated(this.declaredClass+"::getValues() is deprecated. Use get('value') instead.","","2.0");return this.get("value");},_getValueAttr:function(){var obj={};_1.forEach(this._getDescendantFormWidgets(),function(_15){var _16=_15.name;if(!_16||_15.disabled){return;}var _17=_15.get("value");if(typeof _15.checked=="boolean"){if(/Radio/.test(_15.declaredClass)){if(_17!==false){_4.setObject(_16,_17,obj);}else{_17=_4.getObject(_16,false,obj);if(_17===undefined){_4.setObject(_16,null,obj);}}}else{var ary=_4.getObject(_16,false,obj);if(!ary){ary=[];_4.setObject(_16,ary,obj);}if(_17!==false){ary.push(_17);}}}else{var _18=_4.getObject(_16,false,obj);if(typeof _18!="undefined"){if(_4.isArray(_18)){_18.push(_17);}else{_4.setObject(_16,[_18,_17],obj);}}else{_4.setObject(_16,_17,obj);}}});return obj;},isValid:function(){return this.state=="";},onValidStateChange:function(){},_getState:function(){var _19=_1.map(this._descendants,function(w){return w.get("state")||"";});return _1.indexOf(_19,"Error")>=0?"Error":_1.indexOf(_19,"Incomplete")>=0?"Incomplete":"";},disconnectChildren:function(){_1.forEach(this._childConnections||[],_4.hitch(this,"disconnect"));_1.forEach(this._childWatches||[],function(w){w.unwatch();});},connectChildren:function(_1a){var _1b=this;this.disconnectChildren();this._descendants=this._getDescendantFormWidgets();var set=_1a?function(_1c,val){_1b[_1c]=val;}:_4.hitch(this,"_set");set("value",this.get("value"));set("state",this._getState());var _1d=(this._childConnections=[]),_1e=(this._childWatches=[]);_1.forEach(_1.filter(this._descendants,function(_1f){return _1f.validate;}),function(_20){_1.forEach(["state","disabled"],function(_21){_1e.push(_20.watch(_21,function(){_1b.set("state",_1b._getState());}));});});var _22=function(){if(_1b._onChangeDelayTimer){clearTimeout(_1b._onChangeDelayTimer);}_1b._onChangeDelayTimer=setTimeout(function(){delete _1b._onChangeDelayTimer;_1b._set("value",_1b.get("value"));},10);};_1.forEach(_1.filter(this._descendants,function(_23){return _23.onChange;}),function(_24){_1d.push(_1b.connect(_24,"onChange",_22));_1e.push(_24.watch("disabled",_22));});},startup:function(){this.inherited(arguments);this.connectChildren(true);this.watch("state",function(_25,_26,_27){this.onValidStateChange(_27=="");});},destroy:function(){this.disconnectChildren();this.inherited(arguments);}});}); \ No newline at end of file