Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Submit.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-form-action-Submit'>/**
19 </span> * @class Ext.form.action.Submit
20  * @extends Ext.form.action.Action
21  * &lt;p&gt;A class which handles submission of data from {@link Ext.form.Basic Form}s
22  * and processes the returned response.&lt;/p&gt;
23  * &lt;p&gt;Instances of this class are only created by a {@link Ext.form.Basic Form} when
24  * {@link Ext.form.Basic#submit submit}ting.&lt;/p&gt;
25  * &lt;p&gt;&lt;u&gt;&lt;b&gt;Response Packet Criteria&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
26  * &lt;p&gt;A response packet may contain:
27  * &lt;div class=&quot;mdetail-params&quot;&gt;&lt;ul&gt;
28  * &lt;li&gt;&lt;b&gt;&lt;code&gt;success&lt;/code&gt;&lt;/b&gt; property : Boolean
29  * &lt;div class=&quot;sub-desc&quot;&gt;The &lt;code&gt;success&lt;/code&gt; property is required.&lt;/div&gt;&lt;/li&gt;
30  * &lt;li&gt;&lt;b&gt;&lt;code&gt;errors&lt;/code&gt;&lt;/b&gt; property : Object
31  * &lt;div class=&quot;sub-desc&quot;&gt;&lt;div class=&quot;sub-desc&quot;&gt;The &lt;code&gt;errors&lt;/code&gt; property,
32  * which is optional, contains error messages for invalid fields.&lt;/div&gt;&lt;/li&gt;
33  * &lt;/ul&gt;&lt;/div&gt;
34  * &lt;p&gt;&lt;u&gt;&lt;b&gt;JSON Packets&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
35  * &lt;p&gt;By default, response packets are assumed to be JSON, so a typical response
36  * packet may look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
37 {
38     success: false,
39     errors: {
40         clientCode: &quot;Client not found&quot;,
41         portOfLoading: &quot;This field must not be null&quot;
42     }
43 }&lt;/code&gt;&lt;/pre&gt;
44  * &lt;p&gt;Other data may be placed into the response for processing by the {@link Ext.form.Basic}'s callback
45  * or event handler methods. The object decoded from this JSON is available in the
46  * {@link Ext.form.action.Action#result result} property.&lt;/p&gt;
47  * &lt;p&gt;Alternatively, if an {@link Ext.form.Basic#errorReader errorReader} is specified as an {@link Ext.data.reader.Xml XmlReader}:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
48     errorReader: new Ext.data.reader.Xml({
49             record : 'field',
50             success: '@success'
51         }, [
52             'id', 'msg'
53         ]
54     )
55 &lt;/code&gt;&lt;/pre&gt;
56  * &lt;p&gt;then the results may be sent back in XML format:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
57 &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
58 &amp;lt;message success=&quot;false&quot;&amp;gt;
59 &amp;lt;errors&amp;gt;
60     &amp;lt;field&amp;gt;
61         &amp;lt;id&amp;gt;clientCode&amp;lt;/id&amp;gt;
62         &amp;lt;msg&amp;gt;&amp;lt;![CDATA[Code not found. &amp;lt;br /&amp;gt;&amp;lt;i&amp;gt;This is a test validation message from the server &amp;lt;/i&amp;gt;]]&amp;gt;&amp;lt;/msg&amp;gt;
63     &amp;lt;/field&amp;gt;
64     &amp;lt;field&amp;gt;
65         &amp;lt;id&amp;gt;portOfLoading&amp;lt;/id&amp;gt;
66         &amp;lt;msg&amp;gt;&amp;lt;![CDATA[Port not found. &amp;lt;br /&amp;gt;&amp;lt;i&amp;gt;This is a test validation message from the server &amp;lt;/i&amp;gt;]]&amp;gt;&amp;lt;/msg&amp;gt;
67     &amp;lt;/field&amp;gt;
68 &amp;lt;/errors&amp;gt;
69 &amp;lt;/message&amp;gt;
70 &lt;/code&gt;&lt;/pre&gt;
71  * &lt;p&gt;Other elements may be placed into the response XML for processing by the {@link Ext.form.Basic}'s callback
72  * or event handler methods. The XML document is available in the {@link Ext.form.Basic#errorReader errorReader}'s
73  * {@link Ext.data.reader.Xml#xmlData xmlData} property.&lt;/p&gt;
74  */
75 Ext.define('Ext.form.action.Submit', {
76     extend:'Ext.form.action.Action',
77     alternateClassName: 'Ext.form.Action.Submit',
78     alias: 'formaction.submit',
79
80     type: 'submit',
81
82 <span id='Ext-form-action-Submit-cfg-clientValidation'>    /**
83 </span>     * @cfg {Boolean} clientValidation Determines whether a Form's fields are validated
84      * in a final call to {@link Ext.form.Basic#isValid isValid} prior to submission.
85      * Pass &lt;tt&gt;false&lt;/tt&gt; in the Form's submit options to prevent this. Defaults to true.
86      */
87
88     // inherit docs
89     run : function(){
90         var form = this.form;
91         if (this.clientValidation === false || form.isValid()) {
92             this.doSubmit();
93         } else {
94             // client validation failed
95             this.failureType = Ext.form.action.Action.CLIENT_INVALID;
96             form.afterAction(this, false);
97         }
98     },
99
100 <span id='Ext-form-action-Submit-method-doSubmit'>    /**
101 </span>     * @private
102      * Perform the submit of the form data.
103      */
104     doSubmit: function() {
105         var formEl,
106             ajaxOptions = Ext.apply(this.createCallback(), {
107                 url: this.getUrl(),
108                 method: this.getMethod(),
109                 headers: this.headers
110             });
111
112         // For uploads we need to create an actual form that contains the file upload fields,
113         // and pass that to the ajax call so it can do its iframe-based submit method.
114         if (this.form.hasUpload()) {
115             formEl = ajaxOptions.form = this.buildForm();
116             ajaxOptions.isUpload = true;
117         } else {
118             ajaxOptions.params = this.getParams();
119         }
120
121         Ext.Ajax.request(ajaxOptions);
122
123         if (formEl) {
124             Ext.removeNode(formEl);
125         }
126     },
127
128 <span id='Ext-form-action-Submit-method-getParams'>    /**
129 </span>     * @private
130      * Build the full set of parameters from the field values plus any additional configured params.
131      */
132     getParams: function() {
133         var nope = false,
134             configParams = this.callParent(),
135             fieldParams = this.form.getValues(nope, nope, this.submitEmptyText !== nope);
136         return Ext.apply({}, fieldParams, configParams);
137     },
138
139 <span id='Ext-form-action-Submit-method-buildForm'>    /**
140 </span>     * @private
141      * Build a form element containing fields corresponding to all the parameters to be
142      * submitted (everything returned by {@link #getParams}.
143      * NOTE: the form element is automatically added to the DOM, so any code that uses
144      * it must remove it from the DOM after finishing with it.
145      * @return HTMLFormElement
146      */
147     buildForm: function() {
148         var fieldsSpec = [],
149             formSpec,
150             formEl,
151             basicForm = this.form,
152             params = this.getParams(),
153             uploadFields = [];
154
155         basicForm.getFields().each(function(field) {
156             if (field.isFileUpload()) {
157                 uploadFields.push(field);
158             }
159         });
160
161         function addField(name, val) {
162             fieldsSpec.push({
163                 tag: 'input',
164                 type: 'hidden',
165                 name: name,
166                 value: Ext.String.htmlEncode(val)
167             });
168         }
169
170         // Add the form field values
171         Ext.iterate(params, function(key, val) {
172             if (Ext.isArray(val)) {
173                 Ext.each(val, function(v) {
174                     addField(key, v);
175                 });
176             } else {
177                 addField(key, val);
178             }
179         });
180
181         formSpec = {
182             tag: 'form',
183             action: this.getUrl(),
184             method: this.getMethod(),
185             target: this.target || '_self',
186             style: 'display:none',
187             cn: fieldsSpec
188         };
189
190         // Set the proper encoding for file uploads
191         if (uploadFields.length) {
192             formSpec.encoding = formSpec.enctype = 'multipart/form-data';
193         }
194
195         // Create the form
196         formEl = Ext.DomHelper.append(Ext.getBody(), formSpec);
197
198         // Special handling for file upload fields: since browser security measures prevent setting
199         // their values programatically, and prevent carrying their selected values over when cloning,
200         // we have to move the actual field instances out of their components and into the form.
201         Ext.Array.each(uploadFields, function(field) {
202             if (field.rendered) { // can only have a selected file value after being rendered
203                 formEl.appendChild(field.extractFileInput());
204             }
205         });
206
207         return formEl;
208     },
209
210
211
212 <span id='Ext-form-action-Submit-method-onSuccess'>    /**
213 </span>     * @private
214      */
215     onSuccess: function(response) {
216         var form = this.form,
217             success = true,
218             result = this.processResponse(response);
219         if (result !== true &amp;&amp; !result.success) {
220             if (result.errors) {
221                 form.markInvalid(result.errors);
222             }
223             this.failureType = Ext.form.action.Action.SERVER_INVALID;
224             success = false;
225         }
226         form.afterAction(this, success);
227     },
228
229 <span id='Ext-form-action-Submit-method-handleResponse'>    /**
230 </span>     * @private
231      */
232     handleResponse: function(response) {
233         var form = this.form,
234             errorReader = form.errorReader,
235             rs, errors, i, len, records;
236         if (errorReader) {
237             rs = errorReader.read(response);
238             records = rs.records;
239             errors = [];
240             if (records) {
241                 for(i = 0, len = records.length; i &lt; len; i++) {
242                     errors[i] = records[i].data;
243                 }
244             }
245             if (errors.length &lt; 1) {
246                 errors = null;
247             }
248             return {
249                 success : rs.success,
250                 errors : errors
251             };
252         }
253         return Ext.decode(response.responseText);
254     }
255 });
256 </pre>
257 </body>
258 </html>