5

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">&times;</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">&times;</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>
peterh
  • 11,875
  • 18
  • 85
  • 108
pdf2e
  • 177
  • 1
  • 3
  • 16

3 Answers3

1

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.

dh1tw
  • 1,411
  • 2
  • 23
  • 29
  • I don't see anything happen when I click submit. – pdf2e Mar 23 '14 at 23:14
  • 1
    Then it looks like your Submit Button is not bound to the form. Can you post the rendered HTML code? – dh1tw Mar 23 '14 at 23:28
  • I got it posted. Sorry about the formatting I could not get it to tab over. Thank you. – pdf2e Mar 23 '14 at 23:51
  • In your ajax request you want to submit the data of your form with the id="login". Try data: $("#login").serialize() Check for error messages in the Debug Tools > Console – dh1tw Mar 24 '14 at 00:05
  • Thanks. I gave it a shot, but still nothing. I’m not even getting the console.log("clicked") call of the button press. – pdf2e Mar 24 '14 at 00:20
  • then try to fix that first. Remove the ajax query first, and make sure that your button is triggered. btw it's better to use $("#register").on("click", function(){....}) – dh1tw Mar 24 '14 at 00:26
  • I actually got it working with Ajax. But Im having a problem with form validation. I posted the script. Thanks again for your help. – pdf2e Mar 25 '14 at 01:05
0

You have two possibilities:

  1. Via a HTML post request

Put <button> into <form>. Change the type of the submit button to type="submit" and fix the form attributes by adding an action and fixing the typo in the method.

  1. Via an AJAX request.

Add an id to the submit button and attach a click-event to the button where you do the AJAX request.

<script>
    $('#login').on('click', function (e) {
        // login action
    });
</script>

For further information read http://getbootstrap.com/javascript/#modals-examples

Daniel
  • 3,092
  • 3
  • 32
  • 49
  • Thanks for the reply. I have been trying to get Ajax working but my JS is not up to par. I added what I're Tried to the code base in first post. – pdf2e Mar 23 '14 at 22:59
0

I had a similar problem and getting rid of data-dismiss="modal" fixed it for me.

It doesn't answer your question so much, but people with the same issue end up on this page, and perhaps this will help them.

CodyBugstein
  • 21,984
  • 61
  • 207
  • 363