views:

444

answers:

1

hi,

when submitting my form using jQuery form plugin, the request received by the target view is different than that received when the form is submitted in the standard way (with no javascript), and my Django template does not render as expected. When submitted in the standard way, the template renders the form errors (the "form.[field_name].errors), while it doesn't when submitted via javascript. Using the javascript submit, how can I get a request allowing to render the template as it does using the standard submit? The code and the diff between the request objects received in both cases are shown below.

thanks jul

javascript code:

var is_geocoded = false;
var interval;

$(function(){

    $("#submit").click(function() {  
        var options = { 
            beforeSubmit:  getPosition,  // pre-submit callback 
            success:       showResponse  // post-submit callback       
        }; 

        // bind form using 'ajaxForm' 
        $('#addresto').ajaxForm(options); 
    });  

});

function getPosition() {

    var geocoder =  new GClientGeocoder();
    var country = $("#id_country").val();
    var city = $("#id_city").val();
    var postal_code = $("#id_postal_code").val();
    var street_number = $("#id_street_number").val();
    var street = $("#id_street").val();
    var address = street_number+", "+street+", "+postal_code+", "+city+", "+country;

    geocoder.getLatLng( address, function(point) {

        if (point) {

            $("#id_latitude").val(point.lat())
            $("#id_longitude").val(point.lng())
            is_geocoded = true;
        } else {
            is_geocoded = true;
        }
    });

    interval = setInterval("doSubmit()", 500);

    return false;
}

function doSubmit() {

    if (is_geocoded) {
        $("#addresto").ajaxSubmit();
        clearInterval(interval);
    }
}

Django template code:

<form id="addresto" action="" method="POST">

<p><label for="id_name">Name:</label>{{form.name.errors}} {{ form.name }} </p>
<p><label for="id_country">Country:</label>{{form.country.errors}} {{ form.country }} </p>

<!-- more stuff -->

<p style="clear: both;"><input type="Submit" id="submit" value="Submit" /></p>
</form>

Here's the difference between the requests received by the view with standard submit and with javascript submit:

xxx@xxx:~$ diff javascript_submit standard_submit 
7c7
<  'CONTENT_TYPE': 'application/x-www-form-urlencoded; charset=UTF-8',
---
>  'CONTENT_TYPE': 'application/x-www-form-urlencoded',
24c24
<  'HTTP_ACCEPT': '*/*',
---
>  'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
28d27
<  'HTTP_CACHE_CONTROL': 'no-cache',
33d31
<  'HTTP_PRAGMA': 'no-cache',
36d33
<  'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
70c67
<  'wsgi.input': <socket._fileobject object at 0x891d064>,
---
>  'wsgi.input': <socket._fileobject object at 0x898b09c>,
+4  A: 

The reason the errors do not appear when you submit via ajax is that you aren't refreshing the page.

You'll need to pass json, or xml back to your javascript and insert the errors in to the page that way.

You could also just render the form to a blob of html and overwrite the current form on the page (but this is a little more complicated and isn't as efficient)

basically I would reccomende just using django's request.is_ajax() method to determine if the form is being submitted with ajax, and return json for ajax requests

Jiaaro
+1 although I personally prefer giving ajax requests a different URL namespace, possibly just by putting `json` in the path somewhere.
TokenMacGuy
Thanks for the tips. Since I don't really need ajax here, I'll just use javascript, so that I don't have to change my view.
jul