Roo/form/Action.js
[roojs1] / Roo / form / Action.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11  
12  /**
13  * @class Roo.form.Action
14  * Internal Class used to handle form actions
15  * @constructor
16  * @param {Roo.form.BasicForm} el The form element or its id
17  * @param {Object} config Configuration options
18  */
19
20 Roo.namespace('Roo.form');
21  
22  
23 // define the action interface
24 Roo.form.Action = function(form, options){
25     this.form = form;
26     this.options = options || {};
27 };
28 /**
29  * Client Validation Failed
30  * @const 
31  */
32 Roo.form.Action.CLIENT_INVALID = 'client';
33 /**
34  * Server Validation Failed
35  * @const 
36  */
37 Roo.form.Action.SERVER_INVALID = 'server';
38  /**
39  * Connect to Server Failed
40  * @const 
41  */
42 Roo.form.Action.CONNECT_FAILURE = 'connect';
43 /**
44  * Reading Data from Server Failed
45  * @const 
46  */
47 Roo.form.Action.LOAD_FAILURE = 'load';
48
49 Roo.form.Action.prototype = {
50     type : 'default',
51     failureType : undefined,
52     response : undefined,
53     result : undefined,
54
55     // interface method
56     run : function(options){
57
58     },
59
60     // interface method
61     success : function(response){
62
63     },
64
65     // interface method
66     handleResponse : function(response){
67
68     },
69
70     // default connection failure
71     failure : function(response){
72         
73         this.response = response;
74         this.failureType = Roo.form.Action.CONNECT_FAILURE;
75         this.form.afterAction(this, false);
76     },
77
78     processResponse : function(response){
79         this.response = response;
80         if(!response.responseText){
81             return true;
82         }
83         this.result = this.handleResponse(response);
84         return this.result;
85     },
86
87     // utility functions used internally
88     getUrl : function(appendParams){
89         var url = this.options.url || this.form.url || this.form.el.dom.action;
90         if(appendParams){
91             var p = this.getParams();
92             if(p){
93                 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
94             }
95         }
96         return url;
97     },
98
99     getMethod : function(){
100         return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
101     },
102
103     getParams : function(){
104         var bp = this.form.baseParams;
105         var p = this.options.params;
106         if(p){
107             if(typeof p == "object"){
108                 p = Roo.urlEncode(Roo.applyIf(p, bp));
109             }else if(typeof p == 'string' && bp){
110                 p += '&' + Roo.urlEncode(bp);
111             }
112         }else if(bp){
113             p = Roo.urlEncode(bp);
114         }
115         return p;
116     },
117
118     createCallback : function(){
119         return {
120             success: this.success,
121             failure: this.failure,
122             scope: this,
123             timeout: (this.form.timeout*1000),
124             upload: this.form.fileUpload ? this.success : undefined
125         };
126     }
127 };
128
129 Roo.form.Action.Submit = function(form, options){
130     Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
131 };
132
133 Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
134     type : 'submit',
135
136     haveProgress : false,
137     uploadComplete : false,
138     
139     // uploadProgress indicator.
140     uploadProgress : function()
141     {
142         if (!this.form.progressUrl) {
143             return;
144         }
145         
146         if (!this.haveProgress) {
147             Roo.MessageBox.progress("Uploading", "Uploading");
148         }
149         if (this.uploadComplete) {
150            Roo.MessageBox.hide();
151            return;
152         }
153         
154         this.haveProgress = true;
155    
156         var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
157         
158         var c = new Roo.data.Connection();
159         c.request({
160             url : this.form.progressUrl,
161             params: {
162                 id : uid
163             },
164             method: 'GET',
165             success : function(req){
166                //console.log(data);
167                 var rdata = false;
168                 var edata;
169                 try  {
170                    rdata = Roo.decode(req.responseText)
171                 } catch (e) {
172                     Roo.log("Invalid data from server..");
173                     Roo.log(edata);
174                     return;
175                 }
176                 if (!rdata || !rdata.success) {
177                     Roo.log(rdata);
178                     Roo.MessageBox.alert(Roo.encode(rdata));
179                     return;
180                 }
181                 var data = rdata.data;
182                 
183                 if (this.uploadComplete) {
184                    Roo.MessageBox.hide();
185                    return;
186                 }
187                    
188                 if (data){
189                     Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
190                        Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
191                     );
192                 }
193                 this.uploadProgress.defer(2000,this);
194             },
195        
196             failure: function(data) {
197                 Roo.log('progress url failed ');
198                 Roo.log(data);
199             },
200             scope : this
201         });
202            
203     },
204     
205     
206     run : function()
207     {
208         // run get Values on the form, so it syncs any secondary forms.
209         this.form.getValues();
210         
211         var o = this.options;
212         var method = this.getMethod();
213         var isPost = method == 'POST';
214         if(o.clientValidation === false || this.form.isValid()){
215             
216             if (this.form.progressUrl) {
217                 this.form.findField('UPLOAD_IDENTIFIER').setValue(
218                     (new Date() * 1) + '' + Math.random());
219                     
220             } 
221             
222             
223             Roo.Ajax.request(Roo.apply(this.createCallback(), {
224                 form:this.form.el.dom,
225                 url:this.getUrl(!isPost),
226                 method: method,
227                 params:isPost ? this.getParams() : null,
228                 isUpload: this.form.fileUpload
229             }));
230             
231             this.uploadProgress();
232
233         }else if (o.clientValidation !== false){ // client validation failed
234             this.failureType = Roo.form.Action.CLIENT_INVALID;
235             this.form.afterAction(this, false);
236         }
237     },
238
239     success : function(response)
240     {
241         this.uploadComplete= true;
242         if (this.haveProgress) {
243             Roo.MessageBox.hide();
244         }
245         
246         
247         var result = this.processResponse(response);
248         if(result === true || result.success){
249             this.form.afterAction(this, true);
250             return;
251         }
252         if(result.errors){
253             this.form.markInvalid(result.errors);
254             this.failureType = Roo.form.Action.SERVER_INVALID;
255         }
256         this.form.afterAction(this, false);
257     },
258     failure : function(response)
259     {
260         this.uploadComplete= true;
261         if (this.haveProgress) {
262             Roo.MessageBox.hide();
263         }
264         
265         this.response = response;
266         this.failureType = Roo.form.Action.CONNECT_FAILURE;
267         this.form.afterAction(this, false);
268     },
269     
270     handleResponse : function(response){
271         if(this.form.errorReader){
272             var rs = this.form.errorReader.read(response);
273             var errors = [];
274             if(rs.records){
275                 for(var i = 0, len = rs.records.length; i < len; i++) {
276                     var r = rs.records[i];
277                     errors[i] = r.data;
278                 }
279             }
280             if(errors.length < 1){
281                 errors = null;
282             }
283             return {
284                 success : rs.success,
285                 errors : errors
286             };
287         }
288         var ret = false;
289         try {
290             ret = Roo.decode(response.responseText);
291         } catch (e) {
292             ret = {
293                 success: false,
294                 errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
295                 errors : []
296             };
297         }
298         return ret;
299         
300     }
301 });
302
303
304 Roo.form.Action.Load = function(form, options){
305     Roo.form.Action.Load.superclass.constructor.call(this, form, options);
306     this.reader = this.form.reader;
307 };
308
309 Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
310     type : 'load',
311
312     run : function(){
313         
314         Roo.Ajax.request(Roo.apply(
315                 this.createCallback(), {
316                     method:this.getMethod(),
317                     url:this.getUrl(false),
318                     params:this.getParams()
319         }));
320     },
321
322     success : function(response){
323         
324         var result = this.processResponse(response);
325         if(result === true || !result.success || !result.data){
326             this.failureType = Roo.form.Action.LOAD_FAILURE;
327             this.form.afterAction(this, false);
328             return;
329         }
330         this.form.clearInvalid();
331         this.form.setValues(result.data);
332         this.form.afterAction(this, true);
333     },
334
335     handleResponse : function(response){
336         if(this.form.reader){
337             var rs = this.form.reader.read(response);
338             var data = rs.records && rs.records[0] ? rs.records[0].data : null;
339             return {
340                 success : rs.success,
341                 data : data
342             };
343         }
344         return Roo.decode(response.responseText);
345     }
346 });
347
348 Roo.form.Action.ACTION_TYPES = {
349     'load' : Roo.form.Action.Load,
350     'submit' : Roo.form.Action.Submit
351 };