Monday, December 17, 2007

ExtJs 2.0 Fileupload and Grails

If you are having problem with file uploads using ExtJs and Grails, this might help you.

To upload file with the latest ExtJs 2.0, you need to specify the the Ext.form.BasicForm to be configured as fileupload, just pass "fileUpload:true" to the config options. Then add a textfield as specify the "inputType" as "file". This will get you a ExtJs form with a standard File browser button to choose file.

The tricky part comes next.

Using latest Grails 1 RC4 snapshot, handling fileupload is still very easy -- in fact nothing changed at all on how to upload file. (Follow this guide to the upload details)

However because ExtJs's formpanel is expecting JSON reply, typical HTTP 200 response is not valid and you will get error on the client side Javascript.

The fine print is that, you need to specify the JSON response as normal "text/html" instead of "application/json" type. This is as simple as below:

 // render (someJsonResult as JSON) //won't work
// render ([success:true, responseText:$msg] as JSON) won't work for fileupload
render """{succes:${success}, responseText:"${msg}"}"""


Anonymous said...

Where did you get the impression, that the Content-Type of the response has to be text/html? I do a lot with Grails+Ext and always use the Converters which serve text/json.

render([ success: true, responseText: msg ] as JSON)

would be equivalent...

Seymour Cakes said...

No it won't work with ExtJs fileupload. I have tested and confirm this behaviour -- though I don't fully understand it yet.

You can get the same conclusion after hours of going through the ExtJs forum.

Hugh said...

Thanks, I had the same problem with Ruby on Rails (I was returning with content type JSON) but with content type set to HTML everything is now working.

Jeff Howden said...

It has to be text/html because the response comes back in a hidden iframe. You can confirm this by checking for XHR in the console during a file upload. You won't find any as Ext converts an AJAX form submission to a hidden iframe submission when there's a file upload involved. So, to keep the browser happy, you have to return your response as text/html so the browser thinks it needs to load/render the response. From there the framework takes over, scoops the contents of the page, attempts to decipher a response from it, etc.

Anonymous said...

Thx, I was strugling with this for more than one week, simply changing the Content-Type to html solved everything, thanks a lot!

You rock ;)