ec632fe1005c7344268b1e567138fd9ae6f3ab23.svn-base 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. if (!dojo._hasResource["dijit.form.Form"]) { // _hasResource checks added by
  2. // build. Do not use
  3. // _hasResource directly in your
  4. // code.
  5. dojo._hasResource["dijit.form.Form"] = true;
  6. dojo.provide("dijit.form.Form");
  7. dojo.require("dijit._Widget");
  8. dojo.require("dijit._Templated");
  9. dojo.declare("dijit.form._FormMixin", null, {
  10. /*
  11. * summary: Widget corresponding to <form> tag, for validation and
  12. * serialization
  13. *
  14. * usage: <form dojoType="dijit.form.Form" id="myForm"> Name: <input
  15. * type="text" name="name" /> </form> myObj={name: "John Doe"};
  16. * dijit.byId('myForm').setValues(myObj);
  17. *
  18. * myObj=dijit.byId('myForm').getValues(); TODO: Repeater better
  19. * handling for arrays. Often form elements have names with [] like
  20. * people[3].sex (for a list of people [{name: Bill, sex: M}, ...])
  21. *
  22. */
  23. // HTML <FORM> attributes
  24. action : "",
  25. method : "",
  26. enctype : "",
  27. name : "",
  28. "accept-charset" : "",
  29. accept : "",
  30. target : "",
  31. attributeMap : dojo.mixin(dojo
  32. .clone(dijit._Widget.prototype.attributeMap), {
  33. action : "",
  34. method : "",
  35. enctype : "",
  36. "accept-charset" : "",
  37. accept : "",
  38. target : ""
  39. }),
  40. // execute: Function
  41. // User defined function to do stuff when the user hits the submit
  42. // button
  43. execute : function(/* Object */formContents) {
  44. },
  45. // onCancel: Function
  46. // Callback when user has canceled dialog, to notify container
  47. // (user shouldn't override)
  48. onCancel : function() {
  49. },
  50. // onExecute: Function
  51. // Callback when user is about to execute dialog, to notify container
  52. // (user shouldn't override)
  53. onExecute : function() {
  54. },
  55. templateString : "<form dojoAttachPoint='containerNode' dojoAttachEvent='onsubmit:_onSubmit' name='${name}' enctype='multipart/form-data'></form>",
  56. _onSubmit : function(/* event */e) {
  57. // summary: callback when user hits submit button
  58. dojo.stopEvent(e);
  59. this.onExecute(); // notify container that we are about to execute
  60. this.execute(this.getValues());
  61. },
  62. submit : function() {
  63. // summary: programatically submit form
  64. this.containerNode.submit();
  65. },
  66. setValues : function(/* object */obj) {
  67. // summary: fill in form values from a JSON structure
  68. // generate map from name --> [list of widgets with that name]
  69. var map = {};
  70. dojo.forEach(this.getDescendants(), function(widget) {
  71. if (!widget.name) {
  72. return;
  73. }
  74. var entry = map[widget.name] || (map[widget.name] = []);
  75. entry.push(widget);
  76. });
  77. // call setValue() or setChecked() for each widget, according to obj
  78. for (var name in map) {
  79. var widgets = map[name], // array of widgets w/this name
  80. values = dojo.getObject(name, false, obj); // list of values
  81. // for those widgets
  82. if (!dojo.isArray(values)) {
  83. values = [values];
  84. }
  85. if (widgets[0].setChecked) {
  86. // for checkbox/radio, values is a list of which widgets
  87. // should be checked
  88. dojo.forEach(widgets, function(w, i) {
  89. w
  90. .setChecked(dojo.indexOf(values,
  91. w.value) != -1);
  92. });
  93. } else {
  94. // otherwise, values is a list of values to be assigned
  95. // sequentially to each widget
  96. dojo.forEach(widgets, function(w, i) {
  97. w.setValue(values[i]);
  98. });
  99. }
  100. }
  101. /*******************************************************************
  102. * TODO: code for plain input boxes (this shouldn't run for inputs
  103. * that are part of widgets
  104. *
  105. * dojo.forEach(this.containerNode.elements, function(element){ if
  106. * (element.name == ''){return}; // like "continue" var namePath =
  107. * element.name.split("."); var myObj=obj; var
  108. * name=namePath[namePath.length-1]; for(var
  109. * j=1,len2=namePath.length;j<len2;++j) { var p=namePath[j - 1]; //
  110. * repeater support block var nameA=p.split("["); if (nameA.length >
  111. * 1) { if(typeof(myObj[nameA[0]]) == "undefined") {
  112. * myObj[nameA[0]]=[ ]; } // if
  113. *
  114. * nameIndex=parseInt(nameA[1]);
  115. * if(typeof(myObj[nameA[0]][nameIndex]) == "undefined") {
  116. * myObj[nameA[0]][nameIndex]={}; }
  117. * myObj=myObj[nameA[0]][nameIndex]; continue; } // repeater support
  118. * ends
  119. *
  120. * if(typeof(myObj[p]) == "undefined") { myObj=undefined; break; };
  121. * myObj=myObj[p]; }
  122. *
  123. * if (typeof(myObj) == "undefined") { return; // like "continue" }
  124. * if (typeof(myObj[name]) == "undefined" && this.ignoreNullValues) {
  125. * return; // like "continue" }
  126. * // TODO: widget values (just call setValue() on the widget)
  127. *
  128. * switch(element.type) { case "checkbox": element.checked = (name
  129. * in myObj) && dojo.some(myObj[name], function(val){ return
  130. * val==element.value; }); break; case "radio": element.checked =
  131. * (name in myObj) && myObj[name]==element.value; break; case
  132. * "select-multiple": element.selectedIndex=-1;
  133. * dojo.forEach(element.options, function(option){ option.selected =
  134. * dojo.some(myObj[name], function(val){ return option.value == val;
  135. * }); }); break; case "select-one": element.selectedIndex="0";
  136. * dojo.forEach(element.options, function(option){ option.selected =
  137. * option.value == myObj[name]; }); break; case "hidden": case
  138. * "text": case "textarea": case "password": element.value =
  139. * myObj[name] || ""; break; } });
  140. */
  141. },
  142. getValues : function() {
  143. // summary: generate JSON structure from form values
  144. // get widget values
  145. var obj = {};
  146. dojo.forEach(this.getDescendants(), function(widget) {
  147. var value = widget.getValue
  148. ? widget.getValue()
  149. : widget.value;
  150. var name = widget.name;
  151. if (!name) {
  152. return;
  153. }
  154. // Store widget's value(s) as a scalar, except for
  155. // checkboxes which are automatically arrays
  156. if (widget.setChecked) {
  157. if (/Radio/.test(widget.declaredClass)) {
  158. // radio button
  159. if (widget.checked) {
  160. dojo.setObject(name, value, obj);
  161. }
  162. } else {
  163. // checkbox/toggle button
  164. var ary = dojo.getObject(name, false, obj);
  165. if (!ary) {
  166. ary = [];
  167. dojo.setObject(name, ary, obj);
  168. }
  169. if (widget.checked) {
  170. ary.push(value);
  171. }
  172. }
  173. } else {
  174. // plain input
  175. dojo.setObject(name, value, obj);
  176. }
  177. });
  178. /*******************************************************************
  179. * code for plain input boxes (see also dojo.formToObject, can we
  180. * use that instead of this code? but it doesn't understand []
  181. * notation, presumably) var obj = { };
  182. * dojo.forEach(this.containerNode.elements, function(elm){ if
  183. * (!elm.name) { return; // like "continue" } var namePath =
  184. * elm.name.split("."); var myObj=obj; var
  185. * name=namePath[namePath.length-1]; for(var
  186. * j=1,len2=namePath.length;j<len2;++j) { var nameIndex = null; var
  187. * p=namePath[j - 1]; var nameA=p.split("["); if (nameA.length > 1) {
  188. * if(typeof(myObj[nameA[0]]) == "undefined") { myObj[nameA[0]]=[ ]; } //
  189. * if nameIndex=parseInt(nameA[1]);
  190. * if(typeof(myObj[nameA[0]][nameIndex]) == "undefined") {
  191. * myObj[nameA[0]][nameIndex]={}; } } else
  192. * if(typeof(myObj[nameA[0]]) == "undefined") { myObj[nameA[0]]={} } //
  193. * if
  194. *
  195. * if (nameA.length == 1) { myObj=myObj[nameA[0]]; } else {
  196. * myObj=myObj[nameA[0]][nameIndex]; } // if } // for
  197. *
  198. * if ((elm.type != "select-multiple" && elm.type != "checkbox" &&
  199. * elm.type != "radio") || (elm.type=="radio" && elm.checked)) {
  200. * if(name == name.split("[")[0]) { myObj[name]=elm.value; } else { //
  201. * can not set value when there is no name } } else if (elm.type ==
  202. * "checkbox" && elm.checked) { if(typeof(myObj[name]) ==
  203. * 'undefined') { myObj[name]=[ ]; } myObj[name].push(elm.value); }
  204. * else if (elm.type == "select-multiple") { if(typeof(myObj[name]) ==
  205. * 'undefined') { myObj[name]=[ ]; } for (var
  206. * jdx=0,len3=elm.options.length; jdx<len3; ++jdx) { if
  207. * (elm.options[jdx].selected) {
  208. * myObj[name].push(elm.options[jdx].value); } } } // if
  209. * name=undefined; }); // forEach
  210. ******************************************************************/
  211. return obj;
  212. },
  213. isValid : function() {
  214. // TODO: ComboBox might need time to process a recently input value.
  215. // This should be async?
  216. // make sure that every widget that has a validator function returns
  217. // true
  218. return dojo.every(this.getDescendants(), function(widget) {
  219. return !widget.isValid || widget.isValid();
  220. });
  221. }
  222. });
  223. dojo.declare("dijit.form.Form", [dijit._Widget, dijit._Templated,
  224. dijit.form._FormMixin], null);
  225. }