| Version 6 (modified by , 19 years ago) ( diff ) |
|---|
Ajax form submition using Dojo for the client side JavaScript library, 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 submittion without reload.
What do you need :
- Django
- Dojo (v0.3) http://dojotoolkit.org/ an open source javascript toolkit.
- Simple_Json (v1.3) http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.3/docs/index.html used for java <-> python communication.
What do we want to achieve
I will use the model of my current website, a recipe one. When a registred user see the details of a recipe, he can mark it or update his mark by selecting a small drop down list. That's nice but when he clicks ok the whole page is reloaded :/ let's use some Ajax to make it transparent and for the fancy effect we can add fading status message like "Your mark has been updated". The select box proposes a mark from 1 to 5, it is actually a form which is sent to the server via POST, which in django link to a method in the view.py : def details(request) which do the innerwork for the details page generation.
Installing Json
get the SimpleJson from svn.
svn co http://svn.red-bean.com/bob/simplejson/trunk/ json cd json sudo python setup.py install
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)
{
if (type == 'error')
alert('Error when retrieving data from the server!');
else
// de code the simpleJson answer from django ''details'' method.
// it populates a Js array ! straigth so cool !
arrayData = dojo.json.evalJson(data);
// now we update the html using the css id as a pointer to the part
// we want to update
dojo.byId("mark_total").innerHTML = arrayData[1];
dojo.byId("mark_message").innerHTML = arrayData[2];
dojo.byId("mark_status").innerHTML = arrayData[3];
// and the fancy fading effect
dojo.lfx.html.highlight("mark_status", [255, 151, 58], 700).play(300);
}
function init()
{
var sendFormButton = dojo.byId('sendFormButton');
dojo.event.connect(sendFormButton, 'onclick', 'sendForm')
}
dojo.addOnLoad(init);
</script>
the following HTML code just comes after the upper code snipset.
[... total mark get updated, lets put css id="mark_total" ...]
{% if r.total_mark %}<li><b>Score</b>: <span id="mark_total">{{ r.total_mark }}</span>/5</li>{% endif %}
[....]
{% if not user.is_anonymous %}
{% ifnotequal user.id r.owner_id %}
<form enctype="multipart/form-data" id="myForm" method="post">
<span id="mark_message">{{mark_message}}</span>
<select name="select_mark">
<option value ="1" {% ifequal my_mark 1 %} selected {% endifequal %}>1</option>
<option value ="2" {% ifequal my_mark 2 %} selected {% endifequal %}>2</option>
<option value ="3" {% ifequal my_mark 3 %} selected {% endifequal %}>3</option>
<option value ="4" {% ifequal my_mark 4 %} selected {% endifequal %}>4</option>
<option value ="5" {% ifequal my_mark 5 %} selected {% endifequal %}>5</option>
</select>
</form>
<button id="sendFormButton">Notez</button>
<br/>
<span id="mark_status">{{ mark_status }}</span>
{% endifnotequal %}
{% endif %}
And, voila.
To have a demo use guest as login, guest as password here http://ozserver.no-ip.com:345 or if not working here http://www.cefinban.net. Go to index and pick a recipe, update the mark.
You can also have a look at the screenshot here : http://ozserver.no-ip.com/~greg/images/ajaxdjango.png
Hope it was useful.
I am using dreamhost for hosting, and no sinplejson is installed. Instead put the source in a folder eg /proz/json/simple_json simple_json will contanit init.py ect.
and in your ~/.bash_profile replace/put this
export PYTHONPATH=$PYTHONPATH:$HOME/django/django_src:$HOME/django/django_projects:$HOME/progz/json
log out/in and try import simple_json (or simplejson depends on what source you picked)
coulix@… Gregory Tappero.
Attachments (1)
- json.jar (33.8 KB ) - added by 19 years ago.
Download all attachments as: .zip