[Django]-Django crispy form tab

6👍

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:

  <head>
<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/js/bootstrap-tab.js' %}">  </script>

👤Zollie

0👍

Check these things:

  1. In settings.py you should have CRISPY_TEMPLATE_PACK = 'bootstrap3'
  2. In your static files you should have a bootstrap-tab.js

0👍

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:

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item">
    <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home"
      aria-selected="true">Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile"
      aria-selected="false">Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" id="contact-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact"
      aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">A Tab</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">B tab</div>
  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">C tab</div>
</div>

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

class Tab(Container):
    """
    Tab object. It wraps fields in a div whose default class is "tab-pane" and
    takes a name as first argument. Example::

        Tab('tab_name', 'form_field_1', 'form_field_2', 'form_field_3')
    """
    css_class = 'tab-pane'
    link_template = '%s/layout/tab-link.html'

    def render_link(self, template_pack=TEMPLATE_PACK, **kwargs):
        """
        Render the link for the tab-pane. It must be called after render so css_class is updated
        with active if needed.
        """
        link_template = self.link_template % template_pack
        return render_to_string(link_template, {'link': self})
  1. /root/.pyenv/versions/3.7.3/lib/python3.7/site-packages/crispy_forms/templates/bootstrap3/layout/tab-link.html
<li class="tab-pane{% if 'active' in link.css_class %} active{% endif %}"><a href="#{{ link.css_id }}" data-toggle="tab">{{ link.name|capfirst }}{% if tab.errors %}!{% endif %}</a></li>

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.

0👍

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.

Leave a comment