Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Submit button no longer works with django crispy forms

I've added bootstrap to my pages and trying to get django crispy forms to work. Really all I've done is pip install django-crispy-forms, added crispy_forms to INSTALLED_APPS and changed {{ form }} to {% crispy form %} in my template (after adding bootstrap and jquery to my static dir):

{% load crispy_forms_tags %}

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="." method="post">
{% csrf_token %}
{% crispy form %}
<input type="submit" value="Submit" class="btn btn-success">
</form>

This form used to work just fine. After the change it looks a lot nicer, but the submit button no longer does anything because it gets moved outside the form:

enter image description here

I'm surprised to see the template change affect the layout of the rest of the document. Have I done something wrong or is this a bug?

Django 1.8.1, django-crispy-forms 1.4.0

like image 888
jozxyqk Avatar asked May 20 '15 16:05

jozxyqk


3 Answers

As you are including the form tags, csrf token and submit button in the template yourself, you should use the crispy filter instead of the crispy tag.

<form action="." method="post">
    {% csrf_token %}
    {{ form|crispy }}
    <input type="submit" value="Submit" class="btn btn-success">
</form>

If you want to use the tag, then you can define your submit button inside a FormHelper. See the crispy tag docs for more info.

like image 183
Alasdair Avatar answered Nov 17 '22 19:11

Alasdair


For others who get stuck here using the tag and wanting to add some custom html to their <form>...

You can add the self.helper.form_tag = False property to your helper and it won't append a </form> to the end of your form.

More docs here.

like image 26
mpkasp Avatar answered Nov 17 '22 18:11

mpkasp


To add the submit button to your form, crispy_form's documentation did it this way:

import floppyforms.__future__ as forms # you can use django's own ModelForm here
from crispy_forms.helper import FormHelper
from django.core.urlresolvers import reverse_lazy

class YourForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(YourForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_method = 'post' # this line sets your form's method to post
        self.helper.form_action = reverse_lazy('your_post_url') # this line sets the form action
        self.helper.layout = Layout( # the order of the items in this layout is important
            'field1_of_your_model',  # field1 will appear first in HTML
            'field2_of_your_model',  # field2 will appear second in HTML
            # this is how to add the submit button to your form and since it is the last item in this tuple, it will be rendered last in the HTML
            Submit('submit', u'Submit', css_class='btn btn-success'), 
    )

    class Meta:
        model = YourModel

Then, in your template, all you have to do is this

{% load crispy_forms_tags %}
{% crispy form %}

And that's it. There is no need to write ANY html in your template.

I think the whole point of crispy_forms is to define HTML in Python. So that you don't have to write much HTML in your template.


Some additional notes:

Since you are using bootstrap. There are three more fields that will be helpful to you, inside __init__() defined above, add these if you need them:

self.helper.form_class = 'form-horizontal' # if you want to have a horizontally layout form
self.helper.label_class = 'col-md-3' # this css class attribute will be added to all of the labels in your form. For instance, the "Username: " label will have 'col-md-3'
self.helper.field_class = 'col-md-9' # this css class attribute will be added to all of the input fields in your form. For isntance, the input text box for "Username" will have 'col-md-9'
like image 8
Cheng Avatar answered Nov 17 '22 19:11

Cheng