Subversion Repositories Applications.papyrus

Rev

Blame | Last modification | View Log | RSS feed

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 <form> tag, for validation and serialization

                usage:
                        <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}, ...])

                */

                // HTML <FORM> attributes

                action: "",
                method: "",
                enctype: "",
                name: "",
                "accept-charset": "",
                accept: "",
                target: "",

                attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
                        {action: "", method: "", enctype: "", "accept-charset": "", accept: "", target: ""}),

                // execute: Function
                //      User defined function to do stuff when the user hits the submit button
                execute: function(/*Object*/ formContents){},

                // onCancel: Function
                //      Callback when user has canceled dialog, to notify container
                //      (user shouldn't override)
                onCancel: function(){},

                // onExecute: Function
                //      Callback when user is about to execute dialog, to notify container
                //      (user shouldn't override)
                onExecute: function(){},

                templateString: "<form dojoAttachPoint='containerNode' dojoAttachEvent='onsubmit:_onSubmit' name='${name}' enctype='multipart/form-data'></form>",

                _onSubmit: function(/*event*/e) {
                        // summary: callback when user hits submit button
                        dojo.stopEvent(e);
                        this.onExecute();       // notify container that we are about to execute
                        this.execute(this.getValues());
                },

                submit: function() {
                        // summary: programatically submit form
                        this.containerNode.submit();
                },

                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 setChecked() 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(widgets[0].setChecked){
                                        // for checkbox/radio, values is a list of which widgets should be checked
                                        dojo.forEach(widgets, function(w, i){
                                                w.setChecked(dojo.indexOf(values, w.value) != -1);
                                        });
                                }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 value = widget.getValue ? widget.getValue() : widget.value;
                                var name = widget.name;
                                if(!name){ return; }

                                // Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays
                                if(widget.setChecked){
                                        if(/Radio/.test(widget.declaredClass)){
                                                // radio button
                                                if(widget.checked){
                                                        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(widget.checked){
                                                        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;
                },

                isValid: function() {
                        // TODO: ComboBox might need time to process a recently input value.  This should be async?
                        // 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],
        null
);

}