I am now studying Django form
. Right now I am focusing on crispy form
.
For now crispy and then after I master the form
I will move on to Django Admin form
and Django admin model form
.
Django 1.10
Python 3.6.0
I am following these tutorials:
https://blog.bixly.com/awesome-forms-django-crispy-forms
http://django-crispy-forms.readthedocs.io/en/latest/layouts.html#
https://godjango.com/29-crispy-forms/
Here are my source code:
views.py:
from django.views.generic import FormView
from apps.colors.forms import PersonDetailForm
class ColorStudyView(FormView):
template_name = 'colors/study.html'
form_class = PersonDetailForm
success_url = '/'
forms.py:
from crispy_forms.bootstrap import Tab, TabHolder
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout
from django import forms
class NoFormTagCrispyFormMixin(object):
@property
def helper(self):
if not hasattr(self, '_helper'):
self._helper = FormHelper()
self._helper.form_tag = False
return self._helper
class PersonDetailForm(forms.Form):
name = forms.CharField(max_length=100)
age = forms.IntegerField(required=False)
address1 = forms.CharField(max_length=50, required=False)
address2 = forms.CharField(max_length=50, required=False)
city = forms.CharField(max_length=50, required=False)
state = forms.CharField(max_length=50, required=False)
mobile = forms.CharField(max_length=32, required=False)
home = forms.CharField(max_length=32, required=False)
office = forms.CharField(max_length=32, required=False)
twitter = forms.CharField(max_length=100, required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
TabHolder(
Tab('Information',
'name',
'age'
),
Tab('Address',
'address1',
'address2',
'city',
'state'
),
Tab('Contact',
'mobile',
'home',
'office',
'twitter',
)
)
)
self.helper.layout.append(Submit('submit', 'Submit'))
study.html:
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<meta charset="UTF-8">
<title>Study</title>
<form action="" method="POST">
{% crispy form %}
</form>
</head>
<body>
</body>
</html>
Problem:
Tab does not change.
Am I miss something?
Sorry for very basic level question, but this is my first day with Django frontend
Here is my picture. Tab Address
and Contact
are not work.
Update:
Zollie solves my problem. Here is my study.html
{% load staticfiles %}
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<meta charset="UTF-8">
<title>Study</title>
<form action="" method="POST">
{% crispy form %}
</form>
</head>
<body>
<script src="http://code.jquery.com/jquery-1.9.1.js">
</script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js">
</script>
<script type="text/javascript" src="{% static 'bootstrap-tab.js' %}"> </script>
</body>
</html>
And here is my filesystem configuration
/Users/el/Code/siam-sbrand/static
(siam-sbrand) Sarits-MacBook-Air-2:static el$ ls
admin django_extensions img
bootstrap-tab.js file.txt js
dist font rest_framework
4
Answers
Check these things:
CRISPY_TEMPLATE_PACK = 'bootstrap3'
I had the same problem when first I wanted to use the Tabs in crispy forms. The documentation is quite weak unfortunately for this package.
The answer on why TabHolder and Tabs are not working is, because you have to include jquery and javascript in your html template head. Also, you have to download bootstrap-tab.js and put it in your ‘static’ folder in the bootstrap subfolder ie., and you also have to include the path to it in your html .
So, it is not enough if you just include Bootstrap or bootstrap.css in the html head.
Here is an example how it should look like:
Although the question is old and solved, I find it might be worthwhile to add some more observations: I came across the problem and found another cause.
First, I checked and confirmed that I had included the .js files as mentioned in the accepted answer. But the tab still did not work.
I found some bootstrap tab examples, such as https://mdbootstrap.com/docs/jquery/components/tabs/. And I concluded that, to make tab work, one should make sure there is a one-to-one relationship between the href attr of the ‘tab header’ and the id attr of the ‘tab body’. Like this:
Note: pay attention to the href attrs of ‘a’ elements and the id attrs of ‘div’ elements.
I did some experimentation and concluded that: once related .js and other files are imported and href and id attrs are properly set, the tab would work.
Now the problem became “how to make crispy set them properly”.
I checked following files:
1. /root/.pyenv/versions/3.7.3/lib/python3.7/site-packages/crispy_forms/bootstrap.py
I noticed the css_id attr. And I guessed that if one set ‘css_id’ properly, maybe crispy would do the rest. I tried. And it worked like a charm.
Maybe crispy documentation needs some improvement.
If you- like me- search for answer why this solution doesn’t work for you, check if you are using bootstrap 4. To my knowledge tabs from crispy don’t work on 5 at least for now.