I am new to Django and I am trying to figure out how to submit a form inside of a modal. I have two Django apps in question, frontend and login. The frontend app delivers the page, and the login is supposed to process the form. I am using crispy forms to render the forms but cannot get the forms to submit. Been struggling with this for a few days. Read through many posts on this and still can't figure it out. Any help will greatly be appreciated. Thank you so much. I'm using Django version 1.6
frontend app's urls.py:
from django.conf.urls import patterns, url
from django.contrib import admin
from frontend import views
from login.views import registration
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^about/$', views.about, name='about'),
url(r'^contact/$', views.contact, name='contact'),
url(r'^$', 'index', name='index'),
url(r'^$',views.registration, name='register'),
)
frontend app's views.py:
from django.template import RequestContext
from django.shortcuts import render_to_response
from login.forms import RegistrationForm
from login.forms import LoginForm
from login.views import registration
def index(request):
return render_to_response('index.html', {'regform':RegistrationForm(),'loginform': LoginForm()} )
def about(request):
return render_to_response('about.html')
def contact(request):
return render_to_response('contact.html')
login apps's urls.py:
from django.conf.urls import patterns, url
from login import views
urlpatterns = patterns('',
url(r'^register/$', views.registration, name='index.html')
)
login app's views.py:
from django.template import RequestContext
from django.shortcuts import render_to_response
from login.forms import RegistrationForm
def registration(request):
context = RequestContext(request)
registered = False
if request.method == 'POST':
user_form = RegistrationForm(request.POST)
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
user_form = RegistrationForm()
return render_to_response('index.html', {'regform': user_form}, context)
def login(request):
context = RequestContext(request)
login_form = LoginForm()
return render_to_response('index.html', {loginform: login_form}, context)
login app's forms.py:
from django.contrib.auth.models import User
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Field
from crispy_forms.bootstrap import (PrependedText, PrependedAppendedText, FormActions)
from login.models import User
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'first_name','last_name','password')
helper = FormHelper()
helper.form_method = 'POST'
helper.add_input(Submit('save', 'save', css_class='btn-primary'))
class LoginForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'password')
@property
def helper(self):
helper = FormHelper()
helper.form_method = 'POST'
helper.add_input(Submit('save', 'save', css_class='btn-primary'))
return helper
Index.html modal:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Register </h4>
</div>
<div class="modal-body">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab1" data-toggle="tab">Login</a></li>
<li><a href="#tab2" data-toggle="tab">Register</a></li>
</ul>
<form action="" method=post">
<div class="tab-content">
<div class="tab-pane active" id="tab1">
{% crispy loginform %}
</div>
<div class="tab-pane" id="tab2">
{% crispy regform %}
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
Modal with Ajax attempt(snip):
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button id="register" type="button" class="btn btn-primary">Submit</button>
<script>
$('#register').click(function(){
console.log('am i called');
$.ajax({
type: "POST",
url: "/register/",
dataType: "json",
data: $("#login").serialize(),
success: function(data) {
alert(data.message);
}
});
});
</script>
Login view for Ajax request:
def addUser(request):
if request.is_ajax() and request.POST:
data = {request.POST.get('item')}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
raise Http404
As Requested Rendered HTML For Modal:
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Register </h4>
</div>
<div class="modal-body">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab1" data-toggle="tab">Login</a></li>
<li><a href="#tab2" data-toggle="tab">Register</a></li>
</ul>
<form id="login" action="/frontend/register/" method="POST">
<div class="tab-content">
<div class="tab-pane active" id="tab1">
Username* Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters
Password*
</div>
<div class="tab-pane" id="tab2">
Username* Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters
Email address
First name
Last name
Password*
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button id="register" type="button" class="btn btn-primary">Submit</button>
<script>
$('#register').click(function(){
console.log('am i called');
$.ajax({
type: "POST",
url: "/register/",
data: $(regform).serialize(),
success: function(data) {
if (!(data['success'])) {
$(example_form).replaceWith(data['form_html']);
}
else {
$(example_form).find('.success-message').show();
}
},
error: function () {
$(example_form).find('.error-message').show()
}
}
});
});
</script>
</div>
</div>
</div>
</div>
Update Ajax:
<script>
$(document).ready(function() {
var frm = $('#id-registration');
frm.submit(function (e) {
$.ajax({
type: frm.attr('method'), <!-- Get the form's method attribute(defined in login/forms.py -->
url: frm.attr('action'), <!-- Get the form's action attribute(defined in login/forms.py -->
data: $(frm).serialize(), <!-- package the data -->
success: function (data) { <!-- if success return message -->
if (!(data['success'])) {
console.log('ifcalled')
$(frm).replaceWith(data['form_html']); <!-- send replacement form with errors -->
}
else{
console.log('elseCalled')
$("#div-form").html("Thanks!");
// $(frm).find('.success-message').show();
}
},
error: function(data) { <!-- else print error -->
$(frm).find('.error-message').show()
}
});
e.preventDefault(); <!-- problem is here, validation is all ways false -->
});
});
</script>
Update: The form is now being submitted to the database. However form Validation is not functioning. The if/else control seems to always validate false. If I remove form.submit(). It functions and shows form errors, but the page refreshes.
updated views.py:
def addUser(request):
form = RegistrationForm(data=request.POST or None)
if form.is_valid():
# You could actually save through AJAX and return a success code here
form.save()
return {'success': True}
form_html = render_crispy_form(form)
return {'success': False, 'form_html': form_html}
updated Forms.py:
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'first_name','last_name','password')
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-registration'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.form_action = '/register/'
self.helper.add_input(Submit('submit', 'Submit'))
The Problem has been resolved:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script type="text/javascript" src="{% static 'js/jquery-validation- 1.11.1/jquery.validate.js' %}"></script>
<script>
$(document).ready(function () {
var frm = $('#id-registration');
$('#id-registration').validate({
rules: {
username: {required: true},
email: {required: true},
password: {required: true}
},
submitHandler: function(){
$.ajax({//begin
type: 'POST', <!-- Get the form's method attribute(defined in login/forms.py -->
url: frm.attr('action'), <!-- Get the form's action attribute(defined in login/forms.py -->
data: $(frm).serialize(), <!-- package the data -->
success: function(data){
$(frm).hide();
$("#div-form").html("<h3 style='text-align:center;'>Thank you, for Registering!</h3>");
},
error: function(data) { <!-- else print error -->
$("#div-form").html("Failure!");
}//end error
});//end ajax
return false;
}
});
});
</script>
In a first instance I would fire up your Browser Developer Tools (e.g. Firebug in Firefox). In the Network tab monitor closely if your POST request is sent or not.
Once the request is sent, you can inspect the content and answer of your request. This helps to identify if your form catches all the data from the inputs, or if you might have trouble with your urls.py.
In case the form is submitted correctly (Status 200), you can start debugging your Django App.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With