Thursday, May 24, 2012

How can I upload files asynchronously with jQuery?


I would like to upload a file asynchronously with JQuery. This is my HTML:




<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>



And here my javascript:




$(document).ready(function() {
$("#uploadbutton").click(function() {
var filename = $("#file").val();
$.ajax({
type: "POST",
url: "addFile.do",
enctype: 'multipart/form-data',
data: {file: filename},
success: function(){
alert( "Data Uploaded: ");
}
});
});
});



Instead of the file being uploaded, I am only getting the filename. Help?



Current Solution



I am using to upload files the jQuery Form Plugin


Source: Tips4all

12 comments:

  1. There's various ready-made plugins on doing file upload on jquery.

    Doing this kind of uploading hacks is not an enjoyable experience, so people enjoy using ready-made solutions.

    Here's few:


    Ajax File Upload Plugin
    Multiple File Upload Plugin


    You can search more from jquery's plugin -site.

    ReplyDelete
  2. You cannot do AJAX file uploads. They're not supported but you can fake it.

    If you create a iframe on the page (that you can hide with CSS), you can target your form to post to that iframe.

    Because it's a real post, it's not wholly interactive so you'd need to look at requesting the progress of the current upload from your server. This varies massively depending on your server. ASPNET has nicer mechanisms. PHP plain fails but you can use Perl or Apache modifications to get around it.

    If you need multiple file-uploads, it's best to do each file one at a time (to overcome maximum file upload limits). Post the first form to the iframe, monitor its progress using the above and when it has finished, post the second form to the iframe, and so on.

    Or use a Java/Flash solution. They're a lot more flexible in what they can do with their posts...

    ReplyDelete
  3. With HTML5 you CAN make file uploads with Ajax and Jquery. Not only that, you can do file validations(name,size,MIME-type) or handle the progress event with the html5 progress tag(or a div).
    Recently I had to make a file uploader but I didn't want to use flash nor Iframes or plugins and after some research I came up with the solution.

    The HTML:

    <form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
    </form>
    <progress></progress>


    First you can do some validation if you want. For example in the onChange event of the file.

    $(':file').change(function(){
    var file = this.files[0];
    name = file.name;
    size = file.size;
    type = file.type;
    //your validation
    });


    Now the Ajax submit with the button's click.

    $(':button').click(function(){
    var formData = new FormData($('form')[0]);
    $.ajax({
    url: 'upload.php', //server script to process data
    type: 'POST',
    xhr: function() { // custom xhr
    myXhr = $.ajaxSettings.xhr();
    if(myXhr.upload){ // check if upload property exists
    myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
    }
    return myXhr;
    },
    //Ajax events
    beforeSend: beforeSendHandler,
    success: completeHandler,
    error: errorHandler,
    // Form data
    data: formData,
    //Options to tell JQuery not to process data or worry about content-type
    cache: false,
    contentType: false,
    processData: false
    });
    });


    Now if you want to handle the progress.

    function progressHandlingFunction(e){
    if(e.lengthComputable){
    $('progress').attr({value:e.loaded,max:e.total});
    }
    }


    As you can see, with HTML5(and some research) file uploading not only becomes possible but super easy. Try it with Chrome as some of the html5 components of the example aren't avaible in every browser.

    ReplyDelete
  4. I recommend using jsupload plugin for this purpose. Your javascript would be:

    $(document).ready(function() {
    $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
    alert( "server response: " + response);
    }
    });

    ReplyDelete
  5. I just found this awesome tool to do asynchronous file uploading. It is written in jQuery and you can interact with it through jQuery.

    Check out Plupload: http://www.plupload.com/

    It uses these different "runtimes", ranging from HTML 5/4 to Flash to Gears. Here's an example of all the runtimes in one page...

    http://www.plupload.com/example_all_runtimes.php

    I highly recommend Plupload; its awesome!

    I hope this helps.
    Hristo

    ReplyDelete
  6. This AJAX file upload jQuery plugin uploads the file somehwere, and passes the
    response to a callback, nothing else.


    It does not depend on specific HTML, just give it a <input type="file">
    It does not require your server to respond in any particular way
    It does not matter how many files you use, or where they are on the page


    -- Use as little as --

    $('#one-specific-file').ajaxfileupload({
    'action': '/upload.php'
    });


    -- or as much as --

    $('input[type="file"]').ajaxfileupload({
    'action': '/upload.php',
    'params': {
    'extra': 'info'
    },
    'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
    },
    'onStart': function() {
    if(weWantedTo) return false; // cancels upload
    },
    'onCancel': function() {
    console.log('no file selected');
    }
    });

    ReplyDelete
  7. Here's a really good jQuery plugin:
    http://blueimp.github.com/jQuery-File-Upload/

    ReplyDelete
  8. A solution I found was to have the <form> target a hidden iFrame. The iFrame can then run JS to display to the user that it's complete (on page load).

    ReplyDelete
  9. I think others have already answered your question. However, if you also wish to post other data along with file upload, I would suggest you to use this jQuery Form plugin.

    ReplyDelete
  10. I've written this up in a Rails environment. It's only about five lines of JavaScript, if you use the lightweight jQuery-form plugin.

    The challenge is in getting AJAX upload working as the standard remote_form_for doesn't understand multi-part form submission. It's not going to send the file data Rails seeks back with the AJAX request.

    That's where the jQuery-form plugin comes into play.

    Here’s the Rails code for it:

    <% remote_form_for(:image_form,
    :url => { :controller => "blogs", :action => :create_asset },
    :html => { :method => :post,
    :id => 'uploadForm', :multipart => true })
    do |f| %>
    Upload a file: <%= f.file_field :uploaded_data %>
    <% end %>


    Here’s the associated JavaScript:

    $('#uploadForm input').change(function(){
    $(this).parent().ajaxSubmit({
    beforeSubmit: function(a,f,o) {
    o.dataType = 'json';
    },
    complete: function(XMLHttpRequest, textStatus) {
    // XMLHttpRequest.responseText will contain the URL of the uploaded image.
    // Put it in an image element you create, or do with it what you will.
    // For example, if you have an image elemtn with id "my_image", then
    // $('#my_image').attr('src', XMLHttpRequest.responseText);
    // Will set that image tag to display the uploaded image.
    },
    });
    });


    And here’s the Rails controller action, pretty vanilla:

    @image = Image.new(params[:image_form])
    @image.save
    render :text => @image.public_filename


    I’ve been using this for the past few weeks with Bloggity, and it’s worked like a champ.

    ReplyDelete
  11. You can also try this - no Flash needed.

    ReplyDelete
  12. And does it work?

    Here is a Tutorial...

    ReplyDelete