Code


Version 3 (modified by germish@…, 8 years ago) (diff)

mention changeset 3232 and django.utils.simplejson

Form submission

Inner links

Part 1
Ajax basic form submission, Django server answers Ajax call.
Part 2
Handling the form when JavaScript is deactivated.
Part 3
Fixing the frozen fading when user resend the form without waiting for the first fading to end.

Ajax basic form submission, Django server answers Ajax call.

Ajax form submission using Dojo for the client side javaScript toolkit, and simpleJson for the client/server communication.

This will take you through all the steps required to get started and to develop a handy form submission without reload.

What do you need

What do we want to achieve

I will use the model of my current website, a recipe one. When a registered user sees the details of a recipe, the user can rate (mark) it or update their rating (mark) by selecting the mark with a small drop down list. But when the user clicks ok the whole page reloads. We will use some Ajax to make it transparent and fancy effect to show the change to the user. we can add a fading status message like "Your rating has been updated". The select box proposes a rating from 1 to 5, it is actually a form which is sent to the server via POST, which in django links to a method in the view.py : def details(request) which does the innerwork for the details page generation.

Installing Json

get SimpleJson from svn:

svn co http://svn.red-bean.com/bob/simplejson/trunk/ json
cd json
sudo python setup.py install

or get the latest released version from the CheeseShop:

sudo python easy_install simplejson

update: changeset 3232 now offers v1.3 of simplejson in django's utils, so you do not need to download and install simplejson -- just use django.utils.simplejson.

from django.utils import simplejson #in replace of import simple_json

Django part

view.py

def details(request):
        [more stuff]
        if request.POST:
                # Get all the mark for this recipe
                # its not the best way i sould hava an oter entry or table, with total and nbr of marks for
                # each recipe.
                list_mark = Mark.objects.values('mark').filter(recipe__pk=r.id)
                # loop to get the total
                total = 0
                for element in list_mark:
                        total+= element['mark']
                # round it
                total = round((float(total) /  len(list_mark)),1)
                # update the total
                r.total_mark= total
                # save the user mark
                r.save()

                # Now the intersting part for this tut
                import simple_json
                # it was a french string, if we dont't use unicode
                # the result at the output of json in Dojo is wrong.
                message = unicode( message, "utf-8" )
                #
                jsonList = simple_json.dumps((my_mark, total, form_message ,message))
                return HttpResponse(jsonList)
        [more stuff, if not POST return render_to_response('recettes/details.html' ...]

url.py

Just normal url.py, remember the path which will point to the wanted method.

from django.conf.urls.defaults import *

urlpatterns = patterns('',
        [...more...]
        (r'^recettes/(?P<r_cat>[-\w]+)/(?P<r_slug>[-\w]+)/$', 'cefinban.recettes.views.details'),
        [...more...]

Html template with Dojo javascript

Dojo use

{% load i18n %}
{% extends "base.html" %}
{% block script %}
 <script type="text/javascript" src="/media/js/dojo/dojo.js"></script>
 <script type="text/javascript">
 
    dojo.require("dojo.widget.Tooltip");
    dojo.require("dojo.fx.html");
    dojo.require("dojo.event.*");
    dojo.require("dojo.json");

    // point to the same url details.html	 
    function sendForm()
    {
     dojo.io.bind({
                    url: '.',
                    handler: sendFormCallback,
                    formNode: dojo.byId('myForm')
                });
    }

  function sendFormCallback(type, data, evt)
    {