Question

Im having some problems submitting a form (Django-form) with a imagefield with Jquery/ajax POST. Im getting back "Field required" validation errors on the imagefield..

I been trying different solutions with appending formData but with no results so far. Am i on the right track? Please point me in the right direction. Thank you!

Update: I can set the imagefield to required=false and not get the validation error but i want the field to be required and it seems like the form still doesn't submit the image..

The basic function looks like this:

$(function() {
    $('#imageupload').on('click', function() { 

        $('#dialog-modal').load('upload/ #myform');

        $('#dialog-modal').dialog({
              height: 550,
              width: 280,
              modal: true,

              buttons: {
                    Send: function() { 
                        var dialog = $(this), 
                            form = $('#myform'),
                            data = form.serialize();

                    $('.off').remove(); 

                    $.ajax({ 
                        url: 'upload/',
                        data: data,
                        type: 'post',

                        success: function(response) {
                            res = $.parseJSON(response);

                            if (res['status'] == 'OK') {
                                alert('Thank you!'); 
                                dialog.dialog('close'); 
                            }

                            else if (res['status'] == 'bad') {
                                alert('Please try again!');
                                delete res['status'] 
                                var errors = res;

                                $.each(errors, function(key, value) {

                                    var err = $('<span></span>', {
                                                    'class': 'off',
                                                    'text': value
                                            }),
                                        br = $('<br></br>', {
                                            'class': 'off',
                                        }),
                                        input = $('#id_'+key).parent(); 

                                    br.appendTo(input);

                                    err.appendTo(input);

                                    err.css('color', 'red').css('font-size', '10px');

                                });
                            }
                        }

                      });

                    }
                  }
            });


    });
})

Form looks like this, it's in a child html wich is loaded into a jquery dialog/modal box:

    <form method="post" id='myform' enctype="multipart/form-data">
    {% csrf_token %}
    <h1> Upload </h1>
    <p><label for="name">Name:</label></p>
    <div class="fieldWrapper">
    {{ form.name }}
    </div>  
    <br>
    <p><label for="type">Type:</label></p> 
    <div class="fieldWrapper">                
    {{ form.type }}
    </div> 
    <br>
    <p><label for="description">Description:</label></p>  
    <div class="fieldWrapper">
    {{ form.description }}
    </div>  
    <br>  
    <p><label for="picture">Picture:</label></p> 
    <div class="fieldWrapper">                
    {{ form.picture }}
    </div> 
    </form>
Was it helpful?

Solution

There's a known issue with file uploads through jQuery ajax. There are tons of solutions and plugins out there, most of them using an iframe. However, I think the malsup jQuery form plugin provides the easiest of them all, with only a slight modification to your code:

add this inside <head> tag:

<script src="http://malsup.github.com/jquery.form.js"></script> 

change the code within the Send function like so:

buttons: {
    Send: function() { 
        $('.off').remove();
        var dialog = $(this),
            options = {
                url: 'upload/',
                type: 'POST',
                success: function(response) {
                    // everything the same in here
                    }
                };

        $('#myform').ajaxSubmit(options);

    }
  }

Of course, on the server-side you need to make sure to follow the instructions from the documentation on how to bind the files to your form. For the most basic usage, it generally boils down to this:

form = UploadForm(request.POST, request.FILES)

p.s. one final note - as mentioned, it's a known issue, and the solution from malsup uses something called XMLHttpRequest Level 2. It's simply a newer API which provides more functionality to AJAX requests like file uploads, transfer progress information and the ability to send form data. My point being, older browsers don't support it, so bare in mind that if you want legacy-browser-users to make use of your site, you'll need to find an alternative.

OTHER TIPS

Sounds like you've a required attribute on the image field and you're not stopping default behaviour for click function.

$('#imageupload').on('click', function(e) { 
    e.preventDefault();

Bit hard to tell without your HTML code... You should ideally use a form with an id then target that element to bind to the 'submit' event so Enter key and touch events are also handled by the same code.

$('#imageform').on('submit', function (e){ e.preventDefault() // other code here } 

See also: Ajax Upload image

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top