Nicole Esther
Nicole Esther

Reputation: 33

How can I use Django inline formset with Bootstrap-select plugin?

I've been trying to use the Django inline formset with the bootstrap-select plugin from here https://developer.snapappointments.com/bootstrap-select/ and every other thing works perfectly, I'm able to successfully call the plugin on another two selects that I have in my form and I'm using the inline formset to add new authors on my book. When i put the "selectpicker" class, it only works once, when the page is loaded, but when I press the button to add more authors, the select field is not loaded.

So I have a question... can I use the two together? If yes, how? If not, is there any workaround to be able to search in a selection field?

Bellow is a image to how my form looks when i press the big green "Add" button at the end of the form. my form, showing the problem with the author inline formset

You can see that there is only two fields, one less than the first one.

If any code is needed, please let me know and i will add right away.

Thanks!

EDIT:

Here are my codes, as asked by Chris:

My template:

{% extends 'base.html' %}
{% load widget_tweaks %}
{% block content %}
  {% load static %}
  <form method="POST" class="form" action="">
    {% csrf_token %}

    [other fields]
    ...

    <!-- HERE I HAVE MY TWO OTHER SELECT FIELDS WHICH WORK PERFECTLY -->

    <div class="container">
      <div class="col-sm-12">
        <div class="form-group">
          <div class="row">
            <div class="col-sm-6">
              <label>Editora do Livro:</label>
              {{ form.editora_cod_editora|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
            </div>
            <div class="col-sm-6">
              <label>Categoria do Livro:</label>
              {{form.categoria_cod_categoria|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- HERE START MY ONLINE FORM, AS SHOWS THE PRINT -->

    <div class="container">
      <div class="col-sm-12">
        <hr>
        <h4>Adicionar Autor</h4>
        <hr>
        <div class="form-group bg-light rounded ">
        {{ autor_livro.management_form }}
          {% for form in autor_livro.forms %}
            <div class="{% cycle 'row1' 'row2' %} formset_row m-5 inline-form">
              {{ form.autor_cod_autor|add_class:"selectpicker form-control"|attr:"data-live-search='true'" }}
              {{ form.ordinal_autorlivro|add_class:"form-control" }}
              {{ form.autor_funcao|add_class:"form-control" }}
            </div>
          {% endfor %}
          </div>
      </div>
      <div class="container">
        <div class="col-sm-12">
          <div class="form-group">
            <div class="row">
              <div class="col-sm-8"></div>
              <div class="col-sm-4">
                <button type="submit" class="btn-outline-primary btn float-right">Salvar</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </form>
    {% block scripts %}
      <!-- HERE I HAVE MY SCRIPT THAT MAKES THE INLINE FORM WORK WITH THAT PLUGIN -->
      <script src="{% static 'js/jquery.formset.js' %}"></script>
      <script type="text/javascript">
        $('.formset_row').formset({
          addText: 'Adicionar Autor',
          deleteText: 'Remover',
          prefix: 'autorlivro_set'
        });
      </script>
    {% endblock %}
  {% endblock %}

Upvotes: 0

Views: 1149

Answers (1)

Chris
Chris

Reputation: 2212

The answer is the behaviour of the bootstrap-select plugin. You are activating it by using the class "selectpicker". After loading the page some javascript magic takes the elements with the class selectpicker and creates the widget you see. The "select" you now see is not your original <select> but an auxillary widget, your <select> is still there but hidden from your view.

Now when you add another form the javascript magic is not called again, so that you get a new form where your <select> is hidden somewhere from the user's eyes.

In order to get it rendered nicely again you need to run the required javascript after you have added a new form. django-dynamic-formset provides an option called added allowing you define a function which is called after the new form has been added. Form more details see the formset options here.

So define the function and call it after adding a form. In your case your script could look like this:

<script type="text/javascript">
    var activate_select = function(row){
        row.find('.selectpicker').selectpicker();
    };

    $('.formset_row').formset({
        addText: 'Adicionar Autor',
        deleteText: 'Remover',
        prefix: 'autorlivro_set,
        added: activate_select
    });
</script>

Upvotes: 1

Related Questions