FileUpload in Ajax form

266 views
Skip to first unread message

Bayarmunkh Davaadorj

unread,
Apr 20, 2011, 10:28:12 AM4/20/11
to lif...@googlegroups.com
Hi,

I have a problem with using FileUpload stuff in Ajax form.
Here is my code:

      <form class="lift:form.ajax" enctype="multipart/form-data">
<lift:Player.upload>
 <input type="file" value="" id="logo"/> <br />
 <input type="text" value="" id="name" /> <br />
 <input type="submit" value="Submit" />
</lift:Player.upload>  
      </form>

      class Player {
       def upload =
         "#logo" #> fileUpload(f => { println("player logo...") }) &
         "#name" #> text("", (s) => { println("player name...")})
      }

When I do submission, the FileUpload stuff isn't working. 
Can anyone explain what am I doing wrong?

Thanks,

David Pollak

unread,
Apr 20, 2011, 11:52:54 AM4/20/11
to lif...@googlegroups.com

Sorry, but file upload and Ajax don't mix very well.  It's a browser issue, although modern browsers do support file upload via ajax with plugins.

I put together an example of doing Ajax file upload: https://github.com/dpp/starting_point/tree/ajax_upload  I'll enhance the example and ultimately roll it into a module in Lift.
 

Thanks,

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.



--
Lift, the simply functional web framework http://liftweb.net

Becky God

unread,
Apr 21, 2011, 11:34:59 PM4/21/11
to Lift
Thanks for awesome ajax file upload.

So, Does it work in Ajax form?

It seems doesn't... I tried, then got following exception:

uncaught exception: [Exception... "Component returned failure code:
0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIXMLHttpRequest.open]"
nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS
frame :: http://localhost:8080/js/jquery.fileupload.js :: anonymous ::
line 365" data: no]

Thanks,

On Apr 20, 10:52 am, David Pollak <feeder.of.the.be...@gmail.com>
wrote:
> Beginning Scalahttp://www.apress.com/book/view/1430219890

David Pollak

unread,
Apr 22, 2011, 12:14:01 AM4/22/11
to lif...@googlegroups.com
On Thursday, April 21, 2011, Becky God <chi...@gmail.com> wrote:
> Thanks for awesome ajax file upload.
>
> So, Does it work in Ajax form?

Not that I know of. It's a starting point.


--

Lift, the simply functional web framework http://liftweb.net
Simply Lift http://simply.liftweb.net

Beginning Scala http://www.apress.com/book/view/1430219890

Timothy Perrett

unread,
Apr 22, 2011, 4:53:55 AM4/22/11
to lif...@googlegroups.com
You might find this helpful / interesting:

Its a sample of how to use https://github.com/valums/file-uploader which is an LGPL licensed AJAX upload that even supports drag n drop. 

Hope that helps

Tim

Antonio Salazar Cardozo

unread,
Apr 22, 2011, 10:58:29 AM4/22/11
to lif...@googlegroups.com
For what it's worth, I've solved this problem using an old technique (actually a technique used to do AJAX before people used XmlHttpRequest, as I recall) that involves just running it as a regular form submitting to a hidden iframe. In the binding, you treat it like a regular ajaxForm and use fileUpload normally.

There are two changes you need to make to make this work: one client-side and one server-side. Client-side, in JavaScript, you create a hidden iframe (one with display: none) and give it a name. You then set the form's target to that iframe, update its encoding/enctype, change its action so that it matches the request that lift would make via ajax, and make sure to append the value of the submit button properly. The iframe has an onload event handler that simply evaluates the contents of the iframe.

Meantime, server-side, you need to account for IE. Lift serves responses to AJAX requests properly as a JavaScript MIME type, but if you send that to an iframe in IE, IE will try to save it. So, you have to add a bit of code to Boot.scala that will override the MIME type in cases of AJAX file upload requests for IE, resetting it to text/plain, so that IE won't try to save it and your onload handler can do its magic.

The relevant blocks of sample code are at https://gist.github.com/392749 . Note that that is designed assuming there is only one submit button; having more than one can complicate things.
Thanks,
Antonio

PS: This is tested; I've been using it in production for about a year now. It is likely to only work with JsCmd responses, however (i.e., it assumes it has to evaluate the JS directly, so that particular sample code doesn't support JSON).

Also note that this is fragile, as it is intimately bound up with how Lift's JS deals with AJAX, so any changes in future versions of Lift to the JS side of AJAX handling could break it.

David Pollak

unread,
Apr 22, 2011, 12:02:05 PM4/22/11
to lif...@googlegroups.com
On Fri, Apr 22, 2011 at 7:58 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
For what it's worth, I've solved this problem using an old technique (actually a technique used to do AJAX before people used XmlHttpRequest, as I recall) that involves just running it as a regular form submitting to a hidden iframe. In the binding, you treat it like a regular ajaxForm and use fileUpload normally.

There are two changes you need to make to make this work: one client-side and one server-side. Client-side, in JavaScript, you create a hidden iframe (one with display: none) and give it a name. You then set the form's target to that iframe, update its encoding/enctype, change its action so that it matches the request that lift would make via ajax, and make sure to append the value of the submit button properly. The iframe has an onload event handler that simply evaluates the contents of the iframe.

Meantime, server-side, you need to account for IE. Lift serves responses to AJAX requests properly as a JavaScript MIME type, but if you send that to an iframe in IE, IE will try to save it. So, you have to add a bit of code to Boot.scala that will override the MIME type in cases of AJAX file upload requests for IE, resetting it to text/plain, so that IE won't try to save it and your onload handler can do its magic.

The relevant blocks of sample code are at https://gist.github.com/392749 . Note that that is designed assuming there is only one submit button; having more than one can complicate things.

Nifty stuff.  Thanks for sharing!
 
Thanks,
Antonio

PS: This is tested; I've been using it in production for about a year now. It is likely to only work with JsCmd responses, however (i.e., it assumes it has to evaluate the JS directly, so that particular sample code doesn't support JSON).

Also note that this is fragile, as it is intimately bound up with how Lift's JS deals with AJAX, so any changes in future versions of Lift to the JS side of AJAX handling could break it.

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

Antonio Salazar Cardozo

unread,
Apr 22, 2011, 1:01:04 PM4/22/11
to lif...@googlegroups.com

On Friday, April 22, 2011 at 12:02 , David Pollak wrote:

On Fri, Apr 22, 2011 at 7:58 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
For what it's worth, I've solved this problem using an old technique (actually a technique used to do AJAX before people used XmlHttpRequest, as I recall) that involves just running it as a regular form submitting to a hidden iframe. In the binding, you treat it like a regular ajaxForm and use fileUpload normally.

There are two changes you need to make to make this work: one client-side and one server-side. Client-side, in JavaScript, you create a hidden iframe (one with display: none) and give it a name. You then set the form's target to that iframe, update its encoding/enctype, change its action so that it matches the request that lift would make via ajax, and make sure to append the value of the submit button properly. The iframe has an onload event handler that simply evaluates the contents of the iframe.

Meantime, server-side, you need to account for IE. Lift serves responses to AJAX requests properly as a JavaScript MIME type, but if you send that to an iframe in IE, IE will try to save it. So, you have to add a bit of code to Boot.scala that will override the MIME type in cases of AJAX file upload requests for IE, resetting it to text/plain, so that IE won't try to save it and your onload handler can do its magic.

The relevant blocks of sample code are at https://gist.github.com/392749 . Note that that is designed assuming there is only one submit button; having more than one can complicate things.

Nifty stuff.  Thanks for sharing!

Absolutely. Actually, now that I think about it, maybe I should post basically a copy of this onto the wiki somewhere?
Thanks,
Antonio

David Pollak

unread,
Apr 23, 2011, 9:39:43 AM4/23/11
to lif...@googlegroups.com

Wiki would be great.  Having an example project on GitHub would be double-great.
 
Thanks,
Antonio

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

Antonio Salazar Cardozo

unread,
Apr 23, 2011, 10:21:03 AM4/23/11
to lif...@googlegroups.com

On Saturday, April 23, 2011 at 9:39 , David Pollak wrote:



On Fri, Apr 22, 2011 at 10:01 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:

On Friday, April 22, 2011 at 12:02 , David Pollak wrote:

On Fri, Apr 22, 2011 at 7:58 AM, Antonio Salazar Cardozo <savedf...@gmail.com> wrote:
The relevant blocks of sample code are at https://gist.github.com/392749 . Note that that is designed assuming there is only one submit button; having more than one can complicate things.

Nifty stuff.  Thanks for sharing!

Absolutely. Actually, now that I think about it, maybe I should post basically a copy of this onto the wiki somewhere?

Wiki would be great.  Having an example project on GitHub would be double-great. 
I'll see what I can do!
Thanks,
Antonio

Antonio Salazar Cardozo

unread,
May 9, 2011, 10:48:42 AM5/9/11
to lif...@googlegroups.com
It took a couple of weeks, but here's the wiki page explaining the AJAX file upload technique:


And here's the example project that puts it in context:


Thanks,

-- 
Antonio Salazar Cardozo

Maarten Koopmans

unread,
May 9, 2011, 11:21:06 AM5/9/11
to lif...@googlegroups.com
DOn't have time to look at it, but I have exactly the same. WIth progress feedback via comet, do you have that too in the example?

Antonio Salazar Cardozo

unread,
May 9, 2011, 11:49:14 AM5/9/11
to lif...@googlegroups.com

On Monday, May 9, 2011 at 11:21 , Maarten Koopmans wrote:

DOn't have time to look at it, but I have exactly the same. WIth progress feedback via comet, do you have that too in the example?
I did not actually incorporate progress feedback via comet. Feel free to fork and add it if you have a moment, I can pull it back in and update the wiki page!
Antonio

Maarten Koopmans

unread,
May 9, 2011, 1:24:18 PM5/9/11
to lif...@googlegroups.com
I don't need to fork it, see: https://github.com/mbk/ajaxupload_with_comet

and I think I mentioned it here a month back or so....

Antonio Salazar Cardozo

unread,
May 9, 2011, 2:42:46 PM5/9/11
to lif...@googlegroups.com
Coolness; I added links to it on the wiki page.
Antonio

Damian H

unread,
Jul 5, 2011, 4:46:26 AM7/5/11
to Lift
Hi,

Just to say thanks for everyone sharing their ideas on the ajax file
upload problem. I've implemented 'file upload with comet feedback'
technique into my site and it seems to be working well. Really
appreciate the suggestions.

Does anyone know if there's a way to hook into the file upload
processing in between the user pressing the submit button and the file
starting to upload?

I was wondering it's possible to use a hook at that point to only
start the actor checking for upload progress then rather than when the
page is initially loaded. Also, I'm working with big files (1-2G) and
so the upload time is significant. I'm kicking around a few ideas of
things I'd like to be able to do once the file upload has started,
e.g. allowing other users to start to download the file before it's
finished uploading.

Any thoughts would be greatly appreciated.

Thanks

Damian

Antonio Salazar Cardozo

unread,
Jul 5, 2011, 10:08:21 AM7/5/11
to lif...@googlegroups.com
You should be able to hook into the submit event of the form (e.g., $('#myform').submit(function() { watchForFileUpload() })).

You could send down the watchForFileUpload function using SHtml.ajaxCall so that it can invoke a server-side function that notifies the comet actor immediately.
Thanks,
Antonio

reuben doetsch

unread,
Jul 5, 2011, 10:28:28 AM7/5/11
to lif...@googlegroups.com
Sorry if I missed this, but I would love to take a look at this, is the code posted anyplace?

Damian H

unread,
Jul 6, 2011, 6:21:41 AM7/6/11
to lif...@googlegroups.com
@Antonio - thanks for the suggestion. I'll look into it.

@Reuben - I took https://github.com/mbk/ajaxupload_with_comet as my starting point.
Reply all
Reply to author
Forward
0 new messages