jquery form post without refresh the page

1,427 views
Skip to first unread message

Min Hong Tan

unread,
May 3, 2012, 12:44:37 PM5/3/12
to Django users
is there any sample that i can refer to do the ajax style form post
without refresh the whole page?
or backend form.save validation without refresh my form?

Bill Freeman

unread,
May 3, 2012, 1:46:09 PM5/3/12
to django...@googlegroups.com
AJAX

You may require a separate view, but maybe not.

If you search for jQuery and AJAX there should be samples.
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>
>

Kurtis Mullins

unread,
May 3, 2012, 3:16:38 PM5/3/12
to django...@googlegroups.com
Here's something I do.

I have a page where I include {% csrf_token %} and another field. Then I do a simple JQuery .post() call. 

Note, I've tried to pull out a bunch of stuff that isn't specific to the call. It's untested in this form but should work. I tried to include comments to help you understand what's going on.

<script type="text/javascript">
$('div.theme_image, div.theme_name').on("click", function(event) {
    
    // Used later to access 'this' (the calling object)
    var theme = this; 
    
    // Prepare our AJAX Call.
    url = '{% url fireflie.wizard.api.choose_theme %}'; // The URL to the View we're posting to.

    // Building the POST data here.
    data = {
        theme_id: $(this).siblings('input').attr('value'),
        csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').attr('value')
    };
    
    // Post Data to the Server
    var jqxhr = $.post(url, data, function(data) { 
        
        // Do something in here on Success
        // In my example, I wanted to manipulate the calling object, 
        // so it would be "theme" here. If you try to use "this", it won't work.

    });
    
    // On Error:
    jqxhr.error(function() {
       
      // Do something in here in the case of errors.

    });
    
});
</script>

Good luck!
-Kurtis Mullins

Oscar Mederos

unread,
May 4, 2012, 3:58:16 AM5/4/12
to Kurtis Mullins
Hello Kurtis,

On Thursday, May 3, 2012, 3:16:38 PM, you wrote:

> Here's something I do.

> I have a page where I include {% csrf_token %} and another field.
> Then I do a simple JQuery .post() call.

> Note, I've tried to pull out a bunch of stuff that isn't specific
> to the call. It's untested in this form but should work. I tried to
> include comments to help you understand what's going on.

> <script type="text/javascript">
> $('div.theme_image, div.theme_name').on("click", function(event) {
>
> // Used later to access 'this' (the calling object)
> var theme = this;
>
> // Prepare our AJAX Call.
> url = '{% url fireflie.wizard.api.choose_theme %}'; // The URL to the View we're posting to.

> // Building the POST data here.
> data = {
> theme_id: $(this).siblings('input').attr('value'),
> csrfmiddlewaretoken:
> $('input[name=csrfmiddlewaretoken]').attr('value')
> };
>
> ...
>
> });
> </script>

Hello,

Another good option for passing the csrf token is the following one:
https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax.

That helped me a lot, because sometimes you need to render your form
again if it contains errors, and in that case, if you submit it again,
the csrf token won't get updated correctly.

Just imagine the case where the user wants to change his password:
- He clicks on "Change password"
- A modal form (dialog) appears
- The user clicks on "Submit" and he didn't enter the two passwords
correctly.
- The form is rendered again (what I usually do is replace the
<form>..</form> content with the some HTML returned by the server in
the AJAX response). That HTML usually is the rendered form, so that I
don't need to go for each field and set the errors manually using JS.

> Good luck!
> -Kurtis Mullins


--
Oscar Mederos
omed...@gmail.com

Min Hong Tan

unread,
May 4, 2012, 10:09:34 AM5/4/12
to django...@googlegroups.com
Thanks! kurtis, it did helps me. but, to render the form once it return validation error. i need to use javascript returned value and 
manipulate the form.
is there any refresh form content instead of i need to base on returned value and manual add the error message?

Min Hong Tan

unread,
May 4, 2012, 10:14:46 AM5/4/12
to django...@googlegroups.com
hi oscar,

how do you make use of the particular method to be able to render the form only? as you said make use of the 
https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax  and it able to render the form instead of page?
because i'm using kurtis method, if any validation error, i retrieve the data from javascript and manipulate the 
output in html only.

Regards,
MH

Oscar Mederos

unread,
May 4, 2012, 6:56:10 PM5/4/12
to Min Hong Tan
Hello Min,

On Friday, May 4, 2012, 10:14:46 AM, you wrote:

> hi oscar,

> how do you make use of the particular method to be able to render
> the form only? as you said make use of the
> https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax and
> it able to render the form instead of page?
> because i'm using kurtis method, if any validation error, i
> retrieve the data from javascript and manipulate the
> output in html only.

What I usually do is the following:
- Place the content of my form in a separate template file (eg.
password-form.html)
- Using jQuery, I do something like:

//Override the behavior of the 'submit' event of the form.
//Very important to use 'live' instead of 'click'. Otherwise,
//if we change the HTML of the form, this function won't be triggered
//next time we submit the form.
$("#my-form").live('submit', function(e) {
e.preventDefault();
$.ajax({
type: "post",
//DRY. I suppose you already have the url where
//you want to make the POST request in the "action"
//tag of the <form>
url: $("#my-form").attr("action"),
//This automatically get all the values from the
//inputs in the form (eg. a=1&b=2)
data: $("#my-form").serialize(),
dataType: "json",
success: function(data) {
//If there was an error...
if (data.error == 1) {
//All we have to do is replace the body of
//the <form>..</form> with the new HTML
//rendered value of the form returned from
//the server
$("#my-form").replaceWith(data.message);
}
else {
//Do whatever you want here
}
}
});
});

'data' is what the view should return. What I usually do is the
following:
* If there was an error validating the form, then:
- "data.error" will be 1
- "data.message" will have the form rendered
* If the form was validated without problems
- "data.error" will be 0
- "data.message" will have some success message (eg. "Your password
was changed successfully).

- Now, in the view... how do I return the rendered form as HTML?

The "password-form.html" template should look like:

<form id="my-form" action="/some/url">
{% csrf_token %}
...
</form>

And the code of the view could be something like the following (of
course, checking that the request method was POST, etc).

def view(request):
# Create the bounded form (as you usually do)
f = MyForm(request.POST)
if form.is_valid():
form.save()
d = {'error': 0, 'message': 'Some success message'}
else:
d = {'error': 1}
# Here we render the entire HTML text of the form. You can pass
# anything you want in the context...
form_html = render_to_string('password-form.html',..., context_instance=RequestContext(request))
d['message'] = form_html
response = simplejson.dumps(d)
return HttpResponse(response, mimetype='application/json')

I wrote all of it in the editor of my email client, so if something
does not work, just let me know.

Again, very important to use the snippet provided in
https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax


> Regards,
> MH


--
Oscar Mederos
omed...@gmail.com

Min Hong Tan

unread,
May 5, 2012, 1:17:53 AM5/5/12
to django...@googlegroups.com
hi oscar,

Thank you!!! that is awesome! i not even need to manipulate the form using output data json!
thanks! but ,  $("xxx").live  really is important...


Regards,
MH



--
Oscar Mederos
omed...@gmail.com

Min Hong Tan

unread,
May 5, 2012, 1:36:24 PM5/5/12
to django...@googlegroups.com
hi oscar, 

it works, but the problem in jquery load didn't refresh the page after I have loaded.
it will always use the outdated html.  I have tried to use ajaxsetup cache:false etc.
but seems like once it loaded. if form return validation error, even we have close 
and call jquery load again. it will still static and show the last validation error.

how you solve this issue?  seems like more to javascript itself .

Regards,
MH

Oscar Mederos

unread,
May 5, 2012, 4:01:37 PM5/5/12
to Min Hong Tan
Hello Min,

On Saturday, May 5, 2012, 1:36:24 PM, you wrote:

> hi oscar,

> it works, but the problem in jquery load didn't refresh the page after I have loaded.
> it will always use the outdated html. I have tried to use ajaxsetup cache:false etc.
> but seems like once it loaded. if form return validation error, even we have close
> and call jquery load again. it will still static and show the last validation error.

> how you solve this issue? seems like more to javascript itself .

I'm not sure why it isn't modifying the page correctly, because the
following line should do it:

$("#my-form").replaceWith(data.message);

- Are you sure the form isn't being validated in the server-side?
- Are you sure the request is being made to the server? (maybe an error
occurs on the client-side and the request is never made).
- Could you show us the entire code you are using?

I suggest you doing two things:
1) Load the page, and before submitting the form, store the source
code of the page. Then store it again once you submit it, so that you
can compare both source codes.
2) Debug that jQuery code either with Chrome's Developer Tools, or
Firebug for Firefox.

Min Hong Tan

unread,
May 5, 2012, 4:17:34 PM5/5/12
to django...@googlegroups.com
hi Oscar,

I think maybe it over some ajaxsetup({cache:false}) prevention when doing replaceWith.
I have solve the problem by using ".html"  instead of ".replaceWith".

Thank you for your help. very appreciate it .

Regards,
MH

Min Hong Tan

unread,
May 5, 2012, 4:22:35 PM5/5/12
to django...@googlegroups.com
seems like .html has another problem.  it will duplicate itself (even not seen in the screen).
but it did post Number of times when i submit the form.  still need to struggling..bugs still
exist..

Min Hong Tan

unread,
May 5, 2012, 4:28:37 PM5/5/12
to django...@googlegroups.com
i think i use .bind() instead of .live.  because .live will add the event everytimes it .html again.
Thanks
Reply all
Reply to author
Forward
0 new messages