How to POST a django form with AJAX & jQuery
Solution 1:
Since you are using jQuery why not use the following:
<script language="JavaScript">
$(document).ready(function() {
$('#YOUR_FORM').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
data: $(this).serialize(), // get the form data
type: $(this).attr('method'), // GET or POST
url: $(this).attr('action'), // the file to call
success: function(response) { // on success..
$('#DIV_CONTAINING_FORM').html(response); // update the DIV
}
});
return false;
});
});
</script>
EDIT
As pointed out in the comments sometimes the above won't work. So try the following:
<script type="text/javascript">
var frm = $('#FORM-ID');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
$("#SOME-DIV").html(data);
},
error: function(data) {
$("#MESSAGE-DIV").html("Something went wrong!");
}
});
return false;
});
</script>
Solution 2:
You can access the data on the POST request using the name of the variable, in your case:
request.POST["noteid"]
request.POST["phase"]
request.POST["parent"]
... etc
The request.POST object is inmutable. You should assign the value to a variable, and then manipulate it.
I would advise you to use this JQuery plugin, so you can write normal HTML forms and then get them "upgraded" to AJAX. Having $.post everywhere in you code is kind of tedious.
Also, use the Network view on Firebug(for Firefox) or the Developer Tools for Google Chrome so you can view what's being sent by you AJAX calls.
Solution 3:
Something to look out for is when returning the form as an html snipped to a modal.
Views.py
@require_http_methods(["POST"])
def login(request):
form = BasicLogInForm(request.POST)
if form.is_valid():
print "ITS VALID GO SOMEWHERE"
pass
return render(request, 'assess-beta/login-beta.html', {'loginform':form})
Simple view to return the html snipped
Form html Snipped
<form class="login-form" action="/login_ajx" method="Post">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="header">Authenticate</h4>
</div>
<div class="modal-body">
{%if form.non_field_errors %}<div class="alert alert-danger">{{ form.non_field_errors }}</div>{%endif%}
<div class="fieldWrapper form-group has-feedback">
<label class="control-label" for="id_email">Email</label>
<input class="form-control" id="{{ form.email.id_for_label }}" type="text" name="{{ form.email.html_name }}" value="{%if form.email.value %}{{ form.email.value }}{%endif%}">
{%if form.email.errors %}<div class="alert alert-danger">{{ form.email.errors }}</div>{%endif%}
</div>
<div class="fieldWrapper form-group has-feedback">
<label class="control-label" for="id_password">Password</label>
<input class="form-control" id="{{ form.password.id_for_label }}" type="password" name="{{ form.password.html_name}}" value="{%if form.password.value %}{{ form.password.value }}{%endif%}">
{%if form.password.errors %}<div class="alert alert-danger">{{ form.password.errors }}</div>{%endif%}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<input type="submit" value="Sign in" class="btn btn-primary pull-right"/>
</div>
</form>
Page containing the modal
<div class="modal fade" id="LoginModal" tabindex="-1" role="dialog">{% include "assess-beta/login-beta.html" %}</div>
Use the include tag to load the snipped on page load so it is available when you open the modal.
Modal.js
$(document).on('submit', '.login-form', function(){
$.ajax({
type: $(this).attr('method'),
url: this.action,
data: $(this).serialize(),
context: this,
success: function(data, status) {
$('#LoginModal').html(data);
}
});
return false;
});
Using the .on() in this case work like .live() the key being binding the submit event not to the button but to the document.
Solution 4:
As the other answers do work, I prefer to use the jQuery Form Plugin. It fully supports what you want and more. The post view is handled as usual in the Django part, just returning the HTML that is being replaced.
Solution 5:
On the server side, your django code can process the AJAX post the same way it processes other form submissions. For example,
views.py
def save_note(request, space_name):
"""
Saves the note content and position within the table.
"""
place = get_object_or_404(Space, url=space_name)
note_form = NoteForm(request.POST or None)
if request.method == "POST" and request.is_ajax():
print request.POST
if note_form.is_valid():
note_form.save()
msg="AJAX submission saved"
else:
msg="AJAX post invalid"
else:
msg = "GET petitions are not allowed for this view."
return HttpResponse(msg)
I've assumed your NoteForm is a ModelForm -- which it should be -- so it has a save method. Note that in addition to adding the save()
command, I changed your request.is_ajax
to request.is_ajax()
, which is what you want (if you use request.is_ajax
your code will just check whether the request has a method called is_ajax
, which obviously it does).