applegrew / django-select2

This is a Django integration for Select2
MIT License
710 stars 316 forks source link

Select2 not working properly in a Bootstrap modal #577

Closed benmaier closed 4 years ago

benmaier commented 4 years ago

Greetings, thank you so much for this great package that already saved me a lot of work! I'm currently working on developing simple admin-like CRUD-views for a project and am stuck on a particular problem (described below).

As a preamble I just want to add that I'm using the package django-cruds-adminlte. I've described my setup and my problem fully in this issue on their package: https://github.com/oscarmlage/django-cruds-adminlte.

I'm posting here nevertheless because there hasn't been much activity there during the last month so I'm hoping I might be able to solve the problem myself if someone is able to point me in the right direction.

Goal I'm using a custom ModelForm that works as an "Inline" in a parent-ModelForm and pops up rendered as a bootstrap-modal. In this modal-form I'm using a ModelSelect2-widget.

Problem I've hoped that just pointing a ChoiceField to a Select2Widget would suffice for the ChoiceField to work. However, this is not the case. When rendered, the select-element "freezes", meaning the dropdown opens but I cannot type anything.

Code Snippet The complete setup is described in this issue: https://github.com/oscarmlage/django-cruds-adminlte/issues/134. And this is a repository that reproduces the erroneous behavior: https://github.com/benmaier/example-django-crud-admin-lte-select2.

The CRUDViews I'm using in views.py basically auto-generate Model-specific forms that are rendered with crispy forms.

For completion, I'm pasting here the way in which the modal inline-forms are generated in django-cruds-adminlte:

create.html

{% load i18n %}
{% load crud_tags %}

<!-- Modal -->
<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <h4 class="modal-title" id="myModalLabel">{% trans "New" %} {{ model_verbose_name }}</h4>
</div>

<div class="modal-body">
    {% include "cruds/ajax/_form.html" with action='create' %}
</div>

<div class="modal-footer">
</div>

_form.html

{% load i18n %}
{% load crispy_forms_tags %}
{% load crud_tags %}
{% if not form.helper %}
    {{ form.media }}
{% endif %}

<form
    id="{{name}}_{{object.pk}}_addedit"
    action="{% crud_inline_url base_model inline_model action namespace %}"
    method="POST" enctype="multipart/form-data"
    data-replace-inner="#{{name}}_editList"
    data-ajax-submit=""
    data-refresh-inner="#{{name}}_myList"
    data-success="success"
    onsubmit="return false;">
    {% csrf_token %}
    <div class="box-body row">
        <div class="col-md-12">
            {% if form.helper %}
                {% crispy form %}
            {% else %}
                {{ form|crispy }}
            {% endif %}
        </div>
    </div>

    <div class="box-footer">
        <div class="form-group">
            <div class="controls">
                <button
                    id="{{name}}_{{object.pk}}_addedit_submit"
                    type="submit"
                    class="btn btn-primary">{% trans "Submit" %}</button>
                <a href="javascript::void(0);"
                    onclick="$('#{{name}}_editList').html('');"
                    class="btn btn-danger"
                    data-dismiss="modal">{% trans "Cancel" %}</a>
            </div>
        </div>
    </div>
</form>

<script>
    {% if form.helper %}
    $(".modal select:first").val(1).trigger('change.select2');
    $(".modal select:first").parent().parent().hide();
    {% endif %}

    function success() {
        $('#edit_modal').modal('hide');
    }

    $('.modal #submit-id-submit').parent().parent().remove(); // FIXME: Remove the crispy buttons
    $('#edit_modal').modal('show');
</script>
benmaier commented 4 years ago

while typing out the issue I've solved it, but I decided to post it nevertheless because it might help other people. It turns out that this is a long-known problem:

with an easy quick fix:

(remove the tabindex=-1-attribute from the modal)

For my particular case, adding this line to the <script>-section of _form.html sufficed:

$(".modal").removeAttr("tabindex");
codingjoe commented 4 years ago

Thanks @benmaier, I'd with everyone would put as much effort into their questions as you. Also, double kudos for posting it, even though you already found the issue. I hope this will server other well should they encounter a similar problem.

ideesnoires commented 1 year ago

if someone ends up here again, nowadays this problem (and a solution) are published directly from the select2 project: https://select2.org/troubleshooting/common-problems don't use the tabindex solution but set dropdownParent instead