0

I don't understand how to integrate jQuery plugins with my Ajax function to post a Django form. I have seen examples dealing with only one field, the file to upload. But what if my form contains other fields (textbox, select, etc.)?

Here is my html form (I have a drop down list and a file to upload):

<form id="import_form" class="form-horizontal" method="post" enctype="multipart/form-data">{% csrf_token %}
    {{ form.non_field_errors }}
    <div id="fileToImportChoice" class="fieldWrapper">
        {{ form.fileToImport.errors }}
        {{ form.fileToImport }}
    </div>
    <div id="file_to_import" class="fieldWrapper">
        {{ form.csvFile.errors }}
        {{ form.csvFile }}
    </div>
    <input type="button" id="import_button" value="IMPORT" onclick="javascript:display_message('{% url import %}', document.getElementById('import_form'))" />
</form>

Here is my jquery function:

function display_message(link, form)
{
    var datastring = $(form).serialize();
    $.ajax(
    {
        url: link,
        type: 'POST',
        dataType: 'json',
        enctype: "multipart/form-data",
        data: datastring,
        success: function(result)
        {
            //form not valid -> displays errors
            if (result.form_errors)
            {
                //append current errors to the html form
                errors=result.form_errors
                for (var key in errors)
                {
                    $("#"+key+"_errors").html('<ul class="errorlist"><li>'+errors[key]+'</li></ul>');
                    //~ alert(key+': '+errors[key]);
                }
            }
            else
            {
            }
        }
    });
}

First question: should I insert the name of the file in my datastring variable? For the moment, each time I display the form errors, Django complains that my csvFile is empty, even If I have previously selected a file to upload. I guess it's normal with no plugin. Right?

Now, my main question: how to integrate jQuery plugins with my function? I have seen a simple one called Simple-Ajax-Uploader. Here is an example of how to use it:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

So finally... how to send the file data along with the other data of my form? My idea is to call the plugin in my display_message function and then update my datastring variable that contains all the data to post to my view. If so, how?

EDIT: I am looking for a simple plugin, just one file to upload, no need for custom css. And I want it portable (so HTML5 and FormData is excluded).

Community
  • 1
  • 1
rom
  • 3,592
  • 7
  • 41
  • 71

2 Answers2

1

One way to upload whole form with all files in it is to send the form to a hidden iframe and read the iframe's contents for server response. Example code:

<form method="post" action="..." enctype="multipart/form-data" target="iframe-name">
    ...
</form>


<iframe name="iframe-name"></iframe>

You will need to handle the load event on the iframe and use something like this iframe.contentDocument.body.innerHTML to read iframe's contents (server should return HTML with <body> tag for cross-browser compatibility). Actual iframe element can be dynamically created and hidden using JavaScript.

It's rather easy to write such plugin, but on the other hand probably some of the upload plugins available on the Internet use this method to upload files.

HankMoody
  • 3,077
  • 1
  • 17
  • 38
  • Can I send my file field with the other fields in my ajax function using iframe? If so, can you develop your example? – rom Sep 05 '13 at 05:41
  • i didn't use exactly your method, but I used an iframe: http://stackoverflow.com/a/7909924/1875861. No need to use ajax anymore, so the code I had in my ajax function (to deal with errors for example) I just put it in my iframe function. Now it works :). Thank you. – rom Sep 05 '13 at 06:03
0

You can use a FormData object to upload a file via ajax

function display_message(link, form)
{
    var formData = new FormData(form);
    $.ajax(
    {
        url: link,
        type: 'POST',
        dataType: 'json',
        processData: false,
        contentType: false,
        data: formData,
        success: function(result)
        {
            //form not valid -> displays errors
            if (result.form_errors)
            {
                //append current errors to the html form
                errors=result.form_errors
                for (var key in errors)
                {
                    $("#"+key+"_errors").html('<ul class="errorlist"><li>'+errors[key]+'</li></ul>');
                    //~ alert(key+': '+errors[key]);
                }
            }
            else
            {
            }
        }
    });
}
Musa
  • 96,336
  • 17
  • 118
  • 137
  • I know this solution, it is very easy... The problem is: it doesn't work for all the browsers, especially with IE<10. I need a portable solution :(. – rom Sep 04 '13 at 17:16
  • I just checked... It seems too much for what I want to do... I just have one file to upload. And no need for custom css. What plugin would you recommend? – rom Sep 04 '13 at 18:11