5

I put together a simple test of an ajax/jquery post within a django framework, but don't really understand why the output doesn't make it to a template page. Anyone?

I can see the contents of the post in firebug's 'response' tab, but whether I try to return a template or a simple message, nothing happens in the browser itself. Conversely, a non-ajax post works as expected (loads new page, posts message)

I'm a complete newbie to ajax/jquery/django so please excuse my ignorance :)

Eventually, what I'd like to be able to do is to pass arbitrary, non-form variables to a django view via jquery. Possible? Thank you :)

Here's the code --

test.html:

<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script></javascript>
<script type="text/javascript">
   $(document).ready(function() {
       $("#testForm").submit(function(event){
           event.preventDefault();
           $.ajax({
                type:"POST",
                url:"/test_results/"
                    });
       });
       return false;
    });
</script>
</head>
<body>
        <form id="testForm" action="/test_results/" method="post">
            <input type="submit" id="go" name="go" value="Go!">
        </form>
</body>
</html>

views.py:

from django.shortcuts import render_to_response
from django.http import HttpResponse


    def test_ajax(request):
        if request.is_ajax():
            message = "Yes, AJAX!"
        else:
            message = "Not Ajax"
        return HttpResponse(message)
        #alternative test: return render_to_response('test_results.html')

urls.py:

(r'^test_results/$', views.test_ajax),
(r'^test/$', views.test),

and the almost empty test_results.html:

<html>
<head>
</head>
<body>
test results
</body>
</html>
Igor
  • 63
  • 1
  • 1
  • 6
  • Note that your `return false` is at the wrong level; it should be within the `$("#testForm").submit` block, ie one line higher so it's before the closing `});` for that block. – Daniel Roseman Mar 15 '11 at 09:42

2 Answers2

5

I can see the contents of the post in firebug's 'response' tab, but whether I try to return a template or a simple message, nothing happens in the browser itself. Conversely, a non-ajax post works as expected (loads new page, posts message)

If you're getting a response, you're getting a response. You're just not doing anything with it.

Why not alert the data and append it to the <body> for example:

$.ajax({
     type:"POST",
     url:"/test_results/",
     data: {
            'arbitrary-data': 'this is arbitrary data',
            'some-form-field': $("myform input:first").val(), // from form
            'background-color': $("body").css("background-color")
            // all of this data is submitted via POST to your view.
            // in django, request.POST['background-color'] 
     },
     success: function(data){
         alert(data);
         $("body").append(data);
     }
});
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Yuji - your example works great. I guess I was just trying to have the results show up on a 'new' page. I undertand that this defeats the purpose of ajax in a way, but as I mentioned in response to Brandon's suggestion -- I'm trying to understand how 'data' could travel from ajax to a django view and onto a new template. – Igor Mar 14 '11 at 22:53
  • If you want a new page, don't use ajax. Submit the form normally and the resulting HTML will be the response. If you don't want a new page, use ajax and modify your current page (as done in my example) or not at all! You can see in brandons example he logs the response `console.log()`. What you do with it is up to you. – Yuji 'Tomita' Tomita Mar 14 '11 at 23:00
  • I understand, I was just trying to understand how things 'travel' ;) Can I store variables inside of an ajax post that are NOT a part of the submit form? Say, for example, that I wanted to send the value of the template's background color to a django view for processing? – Igor Mar 14 '11 at 23:26
  • Of course, that ajax function is **pure** javascript. There is no HTML involved, other than that you happened to trigger it on an `` form submit event. You could call that on a timer for example! The data you send is arbitrary as well. Check out the $.ajax docs: http://api.jquery.com/jQuery.ajax/ you send data via the `data` parameter. I'll update my post with an example. – Yuji 'Tomita' Tomita Mar 14 '11 at 23:28
  • Brilliant! You're too quick, Yuji. Lol. I'm sure you do it in your sleep, but you just made my day :) Thanks again. – Igor Mar 14 '11 at 23:34
3

You need to add a handler for the response returned by the view:

$.ajax({
    type:"POST",
    url:"/test_results/",
    dataType: "json",
    success: function(json)
    {
        //specifying a dataType of json makes jQuery pre-eval the response for us
        console.log(json.message);
    }
 });

You'll probably also want to encode the response as JavaScript in your view:

try:
    import json
except ImportError:
    import simplejson

def my_view(request):
    if request.is_ajax():
        return HttpResponse(json.dumps({'message' : 'awesome'},
            ensure_ascii=False), mimetype='application/javascript')

Hope that helps you out!

Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • Thanks, Brandon - you've managed to answer my next question -- lol -- how json fits into the whole thing -- but I'm still puzzled: the 'awesome' from your code shows up in the console, but not in the browser. Is this what you intended? I'm trying to figure out what a round trip might look like -- have ajax post to a django view and that view show variables originally posted by ajax. – Igor Mar 14 '11 at 22:35
  • Glad I could help. What you do with the values returned depends on your application. For example, let's say you want to append the value returned to the end of the DOM. In jQuery you could do: $('body').append(json.message); – Brandon Taylor Mar 15 '11 at 00:32