summaryrefslogtreecommitdiff
path: root/includes/js/dijit/form/Form.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dijit/form/Form.js')
-rw-r--r--includes/js/dijit/form/Form.js384
1 files changed, 384 insertions, 0 deletions
diff --git a/includes/js/dijit/form/Form.js b/includes/js/dijit/form/Form.js
new file mode 100644
index 0000000..4ad29f9
--- /dev/null
+++ b/includes/js/dijit/form/Form.js
@@ -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();
+ }
+ }
+ }
+);
+
+}