]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dijit/form/Form.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dijit / form / Form.js
diff --git a/static/dojo-release-1.1.1/dijit/form/Form.js b/static/dojo-release-1.1.1/dijit/form/Form.js
new file mode 100644 (file)
index 0000000..4ad29f9
--- /dev/null
@@ -0,0 +1,384 @@
+if(!dojo._hasResource["dijit.form.Form"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit.form.Form"] = true;
+dojo.provide("dijit.form.Form");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+
+dojo.declare("dijit.form._FormMixin", null,
+       {
+       //
+       //      summary:
+       //              Widget corresponding to HTML form tag, for validation and serialization
+       //
+       //      example:
+       //      |       <form dojoType="dijit.form.Form" id="myForm">
+       //      |               Name: <input type="text" name="name" />
+       //      |       </form>
+       //      |       myObj = {name: "John Doe"};
+       //      |       dijit.byId('myForm').setValues(myObj);
+       //      |
+       //      |       myObj=dijit.byId('myForm').getValues();
+
+       //      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.validate || widget.validate();
+                               if (!valid && !didFocus) {
+                                       // Set focus of the first non-valid widget
+                                       dijit.scrollIntoView(widget.containerNode||widget.domNode);
+                                       widget.focus();
+                                       didFocus = true;
+                               }
+                               return valid;
+                       }), "return item;");
+               },
+               
+               setValues: function(/*object*/obj){
+                       // summary: fill in form values from a JSON structure
+
+                       // 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);
+                       });
+
+                       // call setValue() or setAttribute('checked') for each widget, according to obj
+                       for(var name in map){
+                               var widgets = map[name],                                                // array of widgets w/this name
+                                       values = dojo.getObject(name, false, obj);      // list of values for those widgets
+                               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.setValue(dojo.indexOf(values, w.value) != -1);
+                                       });
+                               }else if(widgets[0]._multiValue){
+                                       // it takes an array (e.g. multi-select)
+                                       widgets[0].setValue(values);
+                               }else{
+                                       // otherwise, values is a list of values to be assigned sequentially to each widget
+                                       dojo.forEach(widgets, function(w, i){
+                                               w.setValue(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 setValue() on the widget)
+
+                               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;
+                               }
+                       });
+                       */
+               },
+
+               getValues: function(){
+                       // summary: generate JSON structure from form values
+
+                       // get widget values
+                       var obj = { };
+                       dojo.forEach(this.getDescendants(), function(widget){
+                               var name = widget.name;
+                               if(!name){ return; }
+
+                               // Single value widget (checkbox, radio, or plain <input> type widget
+                               var value = (widget.getValue && !widget._getValueDeprecated) ? widget.getValue() : widget.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{
+                                               // 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{
+                                       // plain input
+                                       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;
+               },
+
+               // TODO: ComboBox might need time to process a recently input value.  This should be async?
+               isValid: function(){
+                       // summary: make sure that every widget that has a validator function returns true
+                       return dojo.every(this.getDescendants(), function(widget){
+                               return !widget.isValid || widget.isValid();
+                       });
+               }
+       });
+
+dojo.declare(
+       "dijit.form.Form",
+       [dijit._Widget, dijit._Templated, dijit.form._FormMixin],
+       {
+               // summary:
+               // Adds conveniences to regular HTML form
+
+               // HTML <FORM> attributes
+               name: "",
+               action: "",
+               method: "",
+               encType: "",
+               "accept-charset": "",
+               accept: "",
+               target: "",
+
+               templateString: "<form dojoAttachPoint='containerNode' dojoAttachEvent='onreset:_onReset,onsubmit:_onSubmit' name='${name}'></form>",
+
+               attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
+                       {action: "", method: "", encType: "", "accept-charset": "", accept: "", target: ""}),
+
+               execute: function(/*Object*/ formContents){
+                       //      summary:
+                       //              Deprecated: use submit()
+               },
+
+               onExecute: function(){
+                       // summary:
+                       //              Deprecated: use onSubmit()
+               },
+
+               setAttribute: function(/*String*/ attr, /*anything*/ value){
+                       this.inherited(arguments);
+                       switch(attr){
+                               case "encType":
+                                       if(dojo.isIE){ this.domNode.encoding = value; }
+                       }
+               },
+
+               postCreate: function(){
+                       // IE tries to hide encType
+                       if(dojo.isIE && this.srcNodeRef && this.srcNodeRef.attributes){
+                               var item = this.srcNodeRef.attributes.getNamedItem('encType');
+                               if(item && !item.specified && (typeof item.value == "string")){
+                                       this.setAttribute('encType', item.value);
+                               }
+                       }
+                       this.inherited(arguments);
+               },
+
+               onReset: function(/*Event?*/e){ 
+                       //      summary:
+                       //              Callback when user resets the form. This method is intended
+                       //              to be over-ridden. When the `reset` method is called
+                       //              programmatically, the return value from `onReset` is used
+                       //              to compute whether or not resetting should proceed
+                       return true; // Boolean
+               },
+
+               _onReset: function(e){
+                       // create fake event so we can know if preventDefault() is called
+                       var faux = {
+                               returnValue: true, // the IE way
+                               preventDefault: function(){  // not IE
+                                                       this.returnValue = false;
+                                               },
+                               stopPropagation: function(){}, currentTarget: e.currentTarget, target: e.target
+                       };
+                       // if return value is not exactly false, and haven't called preventDefault(), then reset
+                       if(!(this.onReset(faux) === false) && faux.returnValue){
+                               this.reset();
+                       }
+                       dojo.stopEvent(e);
+                       return false;
+               },
+
+               _onSubmit: function(e){
+                       var fp = dijit.form.Form.prototype;
+                       // TODO: remove ths if statement beginning with 2.0
+                       if(this.execute != fp.execute || this.onExecute != fp.onExecute){
+                               dojo.deprecated("dijit.form.Form:execute()/onExecute() are deprecated. Use onSubmit() instead.", "", "2.0");
+                               this.onExecute();
+                               this.execute(this.getValues());
+                       }
+                       if(this.onSubmit(e) === false){ // only exactly false stops submit
+                               dojo.stopEvent(e);
+                       }
+               },
+               
+               onSubmit: function(/*Event?*/e){ 
+                       //      summary:
+                       //              Callback when user submits the form. This method is
+                       //              intended to be over-ridden, but by default it checks and
+                       //              returns the validity of form elements. When the `submit`
+                       //              method is called programmatically, the return value from
+                       //              `onSubmit` is used to compute whether or not submission
+                       //              should proceed
+
+                       return this.isValid(); // Boolean
+               },
+
+               submit: function(){
+                       // summary:
+                       //              programmatically submit form if and only if the `onSubmit` returns true
+                       if(!(this.onSubmit() === false)){
+                               this.containerNode.submit();
+                       }
+               }
+       }
+);
+
+}