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