Reputation: 91
I'm a bit of a newbie when it comes to django, ajax, and jquery, so i apologize ahead of time if my question comes off being trivial.
I've been scratching my head on this one for some time now, but I am trying to use ajax and jquery to submit a Django ModelForm form via a modal dialog window provide by jQuery UI. The problem I am having is that it seems that the form data isn't being passed into the request or that my form object in my views.py file is having a problem parsing the reqest.POST object. Regardless when I submit my form, the form.is_valid() fails and reviewing the form errors I get a "This field is required" for every input of the form. So not sure what I am doing wrong, the form in question worked prior to me trying to "modal"ize it with ajax.
here's my code, maybe a more seasoned eye can see what I missed.
forms.py
from django.forms import ModelForm
from artists.views import Artist
class RegistrationForm(ModelForm):
username = forms.CharField(label=(u'User Name'))
first_name = forms.CharField(label=(u'First Name'))
last_name = forms.CharField(label=(u'Last Name'))
email = forms.EmailField(label=(u'Email'))
password = forms.CharField(label=(u'Password'),
widget=forms.PasswordInput(render_value=False))
password = forms.CharField(label=(u'Verify Password'),
widget=forms.PasswordInput(render_value=False))
class Meta:
model = Artist
exlude = (user, slug, work_email)
views.py
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.shortcut import render
from django.template.defaultfilters import slugify
from django.utils.functional import Promise
from django.utils.encoding import force_text
from django.shortcuts import render
from artists.forms import RegistrationForm
from artists.models import Artist
import json
class LazyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Promise):
return force_text(obj)
return super(LazyEncoder, self).default(obj)
def ValidateEmail(email):
from django.core.validators import validate_email
from django.core.exception import ValidationError
try:
validate_email(email)
return True
except ValidationError:
return False
def ArtistRegistration(request):
form = False
if request.method == 'POST' and request.is_ajax():
form = RegistrationForm(request.POST)
if form.is_Valid():
is_valid = True
username = form.cleaned_data['username']
password = form.cleaned_data['password']
password1 = form.cleaned_data['password1']
email = form.cleaned_data['email']
first_name = form.cleaned_data['first_name'].title()
last_name = form.cleaned_data['last_name'].title()
if ValidateEmail(email) is False:
is_valid = False
message = "Email entry is invalid."
if User.objects.filter(username=username).exists():
is_valid = False
message = "Username already exists."
if password != password1:
is_valid = False
message = "Passwords do not match."
if is_valid is False:
response_dict = {"type": "error"}
response_dict["message"] = message
result = json.dumps(response_dict, cls=LazyEncoder)
return HttpResponse(result, mimetype='application/json')
else:
user = User.objects.create_user)
username = username,
email = email,
password = password,
first_name = first_name,
last_name = last_name_
user.save()
artist = Artist(
user = user,
first_name = first_name,
last_name = last_name,
work_email = email,
slug = slugify('%s %s' % (first_name, last_name)),
department=form.cleaned_data['department'])
artist.save()
response_dict = {'status':1, 'type':'success'}
result = json.dumps(response_dict, cls=LazyEncoder)
return HttpResponse(result, mimetype='application/json')
else:
response_dict = {'type': 'error'}
response_dict['message'] = 'form is invalid'
response_dict['errors'] = json.dumps(form.errors)
result = json.dumps(response_dict, cls=LazyEncoder)
return HttpResponse(result, mimetype='application/json')
else:
form = RegistrationForm()
context = {'form' : form}
return render(request, 'register-modal.html', context)
here is the html that my modal dialog calls: register-modal.html
<form action="{% url 'modal_registration' %}" method="post" id="register_form" name="register_form">
{% csrf_token %}
<table>
<tbody>
<tr>
<th><label for="first_name">First Name:</label></th>
<td>{{ form.first_name }}</td>
</tr>
<tr>
<th><label for="last_name">Last Name:</label></th>
<td>{{ form.last_name }}</td>
</tr>
<tr>
<th><label for="email">Email:</label></th>
<td>{{ form.email }}</td>
</tr>
<tr>
<th><label for="username">Username:</label></th>
<td>{{ form.username }}</td>
</tr>
<tr>
<th><label for="password">Password:</label></th>
<td>{{ form.password }}</td>
</tr>
<tr>
<th><label for="password1">Verify Pswd:</label></th>
<td>{{ form.password1 }}</td>
</tr>
<tr>
<th><label for="department">Department:</label></th>
<td>{{ form.department }}</td>
</tr>
</tbody>
</table>
</form>
<span id="registration_error" name="registration_error" style="color: #FF0000;"></span>
Finally here is the js file that makes all the jquery and ajax calls. I've omitted the csrf part because its copied verbatim from the Django docs.
register.js
$(document).ready(function () {
$.ajaxSetup({traditional: true});
var $register_dialog = $('#modal_register_div').dialog({
autoOpen: false,
title: "User Registration",
closeOnEscape: true,
draggable: false,
resizable: false,
modal: true,
width: 450,
buttons: {
"Register": function () {
var $this = $(this);
var frm = document.form['register_form'];
$.ajax({
type: frm.method,
url: frm.action,
data: $('#register_form').serialize(),
contentType: "application/json;charset=utf-8",
dataType: 'json',
success: function(response){
if(response['type'] == 'success') {
//any extra success functionality goes here
$this.dialog("close");
} else {
$("#registration_error").html(response['message']);
console.log(response['errors']);
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + '\n' + xhr.status + '\n' + ajaxOptions)
}
});
return false;
}
}
});
$('#register_artist').live("click", function () {
$.ajax({
type: 'get',
dataType: 'html',
url: '/register/'
data: {},
success: function(response){
$register_dialog.empty().html(response).dialog('open');
}
});
});
});
the modal dialog is tied to a hidden div on the base template page for my django page, and the js script is loaded on the same page. the dialog is called by clicking on a null href link. anyrate, if anyone can see what I am doing wrong, your input would truly be appreciated.
Thanks!
Upvotes: 4
Views: 2612
Reputation: 91
Figured out what my folly was. In my ajax call I was defining my content type as:
contentType: 'application/json;charset=utf-8'
when it should have been the following:
contentType: 'application/x-www-form-urlencoded;charset=utf-8'
I realized after looking at the header data of my login form which was working compared to my register form, was that in my login form the data was being passed onto the request via "Form_Data" whereas my register form was being passed on as a "Request_Payload". After making the change, everything worked like a charm.
Upvotes: 5