d8eaf6c67f683b6cf3b72a372f79f38fa448b8ab.svn-base 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.form.FormPanel
  8. * @extends Ext.Panel Standard form container.
  9. * <p>
  10. * <b>Although they are not listed, this class also accepts all the
  11. * config options required to configure its internal
  12. * {@link Ext.form.BasicForm}</b>
  13. * </p>
  14. * <br>
  15. * <br>
  16. * FormPanel uses a {@link Ext.layout.FormLayout} internally, and that
  17. * is required for fields and labels to work correctly within the
  18. * FormPanel's layout. To nest additional layout styles within a
  19. * FormPanel, you should nest additional Panels or other containers
  20. * that can provide additional layout functionality. <b>You should not
  21. * override FormPanel's layout.</b> <br>
  22. * <br>
  23. * By default, Ext Forms are submitted through Ajax, using
  24. * {@link Ext.form.Action}. To enable normal browser submission of the
  25. * Ext Form contained in this FormPanel, override the Form's onSubmit,
  26. * and submit methods:<br>
  27. * <br>
  28. *
  29. * <pre><code>
  30. * var myForm = new Ext.form.FormPanel({
  31. * onSubmit : Ext.emptyFn,
  32. * submit : function() {
  33. * this.getForm().getEl().dom.submit();
  34. * }
  35. * });
  36. * </code></pre>
  37. *
  38. * <br>
  39. * @constructor
  40. * @param {Object}
  41. * config Configuration options
  42. */
  43. Ext.FormPanel = Ext.extend(Ext.Panel, {
  44. /**
  45. * @cfg {Number} labelWidth The width of labels. This property
  46. * cascades to child containers.
  47. */
  48. /**
  49. * @cfg {String} itemCls A css class to apply to the x-form-item of
  50. * fields. This property cascades to child containers.
  51. */
  52. /**
  53. * @cfg {String} buttonAlign Valid values are "left," "center" and
  54. * "right" (defaults to "center")
  55. */
  56. buttonAlign : 'center',
  57. /**
  58. * @cfg {Number} minButtonWidth Minimum width of all buttons in
  59. * pixels (defaults to 75)
  60. */
  61. minButtonWidth : 75,
  62. /**
  63. * @cfg {String} labelAlign Valid values are "left," "top" and
  64. * "right" (defaults to "left"). This property cascades to
  65. * child containers if not set.
  66. */
  67. labelAlign : 'left',
  68. /**
  69. * @cfg {Boolean} monitorValid If true the form monitors its valid
  70. * state <b>client-side</b> and fires a looping event with
  71. * that state. This is required to bind buttons to the valid
  72. * state using the config value formBind:true on the button.
  73. */
  74. monitorValid : false,
  75. /**
  76. * @cfg {Number} monitorPoll The milliseconds to poll valid state,
  77. * ignored if monitorValid is not true (defaults to 200)
  78. */
  79. monitorPoll : 200,
  80. /**
  81. * @cfg {String} layout
  82. * @hide
  83. */
  84. layout : 'form',
  85. // private
  86. initComponent : function() {
  87. this.form = this.createForm();
  88. Ext.FormPanel.superclass.initComponent.call(this);
  89. this.addEvents(
  90. /**
  91. * @event clientvalidation If the monitorValid config
  92. * option is true, this event fires repetitively
  93. * to notify of valid state
  94. * @param {Form}
  95. * this
  96. * @param {Boolean}
  97. * valid true if the form has passed
  98. * client-side validation
  99. */
  100. 'clientvalidation');
  101. this.relayEvents(this.form, ['beforeaction', 'actionfailed',
  102. 'actioncomplete']);
  103. },
  104. // private
  105. createForm : function() {
  106. delete this.initialConfig.listeners;
  107. return new Ext.form.BasicForm(null, this.initialConfig);
  108. },
  109. // private
  110. initFields : function() {
  111. var f = this.form;
  112. var formPanel = this;
  113. var fn = function(c) {
  114. if (c.doLayout && c != formPanel) {
  115. Ext.applyIf(c, {
  116. labelAlign : c.ownerCt.labelAlign,
  117. labelWidth : c.ownerCt.labelWidth,
  118. itemCls : c.ownerCt.itemCls
  119. });
  120. if (c.items) {
  121. c.items.each(fn);
  122. }
  123. } else if (c.isFormField) {
  124. f.add(c);
  125. }
  126. }
  127. this.items.each(fn);
  128. },
  129. // private
  130. getLayoutTarget : function() {
  131. return this.form.el;
  132. },
  133. /**
  134. * Provides access to the {@link Ext.form.BasicForm Form} which this
  135. * Panel contains.
  136. *
  137. * @return {Ext.form.BasicForm} The {@link Ext.form.BasicForm Form}
  138. * which this Panel contains.
  139. */
  140. getForm : function() {
  141. return this.form;
  142. },
  143. // private
  144. onRender : function(ct, position) {
  145. this.initFields();
  146. Ext.FormPanel.superclass.onRender.call(this, ct, position);
  147. var o = {
  148. tag : 'form',
  149. method : this.method || 'POST',
  150. id : this.formId || Ext.id()
  151. };
  152. if (this.fileUpload) {
  153. o.enctype = 'multipart/form-data';
  154. }
  155. this.form.initEl(this.body.createChild(o));
  156. },
  157. // private
  158. beforeDestroy : function() {
  159. Ext.FormPanel.superclass.beforeDestroy.call(this);
  160. Ext.destroy(this.form);
  161. },
  162. // private
  163. initEvents : function() {
  164. Ext.FormPanel.superclass.initEvents.call(this);
  165. if (this.monitorValid) { // initialize after render
  166. this.startMonitoring();
  167. }
  168. },
  169. /**
  170. * Starts monitoring of the valid state of this form. Usually this
  171. * is done by passing the config option "monitorValid"
  172. */
  173. startMonitoring : function() {
  174. if (!this.bound) {
  175. this.bound = true;
  176. Ext.TaskMgr.start({
  177. run : this.bindHandler,
  178. interval : this.monitorPoll || 200,
  179. scope : this
  180. });
  181. }
  182. },
  183. /**
  184. * Stops monitoring of the valid state of this form
  185. */
  186. stopMonitoring : function() {
  187. this.bound = false;
  188. },
  189. /**
  190. * This is a proxy for the underlying BasicForm's
  191. * {@link Ext.form.BasicForm#load} call.
  192. *
  193. * @param {Object}
  194. * options The options to pass to the action (see
  195. * {@link Ext.form.BasicForm#doAction} for details)
  196. */
  197. load : function() {
  198. this.form.load.apply(this.form, arguments);
  199. },
  200. // private
  201. onDisable : function() {
  202. Ext.FormPanel.superclass.onDisable.call(this);
  203. if (this.form) {
  204. this.form.items.each(function() {
  205. this.disable();
  206. });
  207. }
  208. },
  209. // private
  210. onEnable : function() {
  211. Ext.FormPanel.superclass.onEnable.call(this);
  212. if (this.form) {
  213. this.form.items.each(function() {
  214. this.enable();
  215. });
  216. }
  217. },
  218. // private
  219. bindHandler : function() {
  220. if (!this.bound) {
  221. return false; // stops binding
  222. }
  223. var valid = true;
  224. this.form.items.each(function(f) {
  225. if (!f.isValid(true)) {
  226. valid = false;
  227. return false;
  228. }
  229. });
  230. if (this.buttons) {
  231. for (var i = 0, len = this.buttons.length; i < len; i++) {
  232. var btn = this.buttons[i];
  233. if (btn.formBind === true && btn.disabled === valid) {
  234. btn.setDisabled(!valid);
  235. }
  236. }
  237. }
  238. this.fireEvent('clientvalidation', this, valid);
  239. }
  240. });
  241. Ext.reg('form', Ext.FormPanel);
  242. Ext.form.FormPanel = Ext.FormPanel;