-
25 Apr 2012 12:38 AM #1
Ext js forms, models and file uploads
Ext js forms, models and file uploads
I would like to clarify how do ext 4 models correlate to form panels. Suppose I have a model, e.g. "User", which has a REST proxy attached.When I want to modify user parameters, i use form's
loadRecord( Ext.data.Model record ) : Ext.form.Basic
method, to set form's field values.After modification, I call "updateRecord" method, to send changes from form to loaded model, and then use model's "save" method, to send changes to server. This works quite well, and seems to fit Ext MVC concepts.
Question
But, the question is: how should I conform to MVC, in case I need to upload file, while modifying user's data (e.g. avatar). According to what I learned from docs, I should switch to using form's "submit" method to send updated data so server, including the file.In this case, I see several drawbacks:- The original model, loaded to the form, will not be updated.
- If I update the model (using "updateRecord", or other way), the model will stay in dirty state, however, changes have already been sent to server.
- The same proxy configuration should be applied to form, as to model, so that I would not need to change server side.
Is this a correct way of implementing file-upload through ext forms? Is there any way to do this using model.save method, to be more MVC-stylish?
-
25 Apr 2012 5:52 AM #2
Would you be able to update your model in the success callback function of the submit action?
-
25 Apr 2012 5:55 AM #3
This is possible, but the model will become dirty in that case, which is not correct, because it is actually saved...
-
26 Jun 2012 6:34 AM #4
i have same issue with my app. mvc + fileupload produce dirty workarounds.
any suggestion on this topic for an easy clean solution? the best would be to have image data posted with the record on save(). submitted data can be either rest or multipart post.
-
26 Jun 2012 6:45 AM #5
As far as I found out, it is impossible to save file as an ajax post. What is done in Ext is a hidden iframe with file field, which is then posted to server. I believe the best solution is to save model data with save() method, which would call ajax post, and after that post file to server (2 requests).
On server side it is required to process incoming data and check wether it has file or not. In case it has a file, note that ext expects reply with content-type = text/html.
-
26 Jun 2012 6:49 AM #6
-
2 Oct 2012 3:33 PM #7
With the File API of HTML5 now, we can use the XMLHttpRequest to upload files. As simple as:
Code:var ajax = new XMLHttpRequest(); ajax.open("POST", "server_url"); ajax.send(formData);
Even we can receive upload progress with:
Code:ajax.upload.addEventListener("progress", uploadProgress, false);
It is available in the major browsers. Im working on a rewrite of Ext.data.Connection to use it with standard BasicForm and remove the iframes. Seems it is not so complex, When I have something that works I will share.
Greetings.
-
2 Oct 2012 3:36 PM #8
Thanks for reply.
looking forward for your data.connection mod
-
4 Oct 2012 7:45 AM #9
Well, here it is:
https://bitbucket.org/fidox/snippets/src/master/extjs/Connection.js
Basically override the request method of standard Connection to remove the form by iframe and add a event listener to the XMLHttpRequest. It is only a test to confirm that it works. And it is
but I not sure this could be use in production.
You can use it simply by adding that file into your index html, and then use the form as always:
* note the progress callback.Code:form.submit({ url: 'url', progress: function(evt) { console.log(evt); }, success: function(form, o) { }, failure: function(form, action) { } });
In the Ext.form.Panel I have a xtype: 'filefield' with no special configurations. Things TODO:
1.- Fallback to the iframes if the browser does not support this feature.
2.- install the progress listener only for upload requests.
I have used the extjs 4.0 code, but for 4.1 could be even more easy. In that case I think I could do that without modifying the request method. Anyway this code should work in 4.1 as is.


Reply With Quote