Closed glennbach closed 3 years ago
Select2 visually replaces the HTML select in favor of its own input.
What do you mean "breaks it" ?
I don't see the JS in your form HTML, are you sure {{ form.media }}
is being rendered ?
I do include the media. What I meant by 'breaks it' (yeah, that wasn't terribly clear, was it), I mean that it no longer accepts any input at all. The input is inert and unresponsive. As I mentioned, if I just display the form by itself, it works fine. It is only when I have crispy display it that it includes the extra class 'select2' that causes the issue. The class is attached to the original select input, but one of the replacement spans inherits it from the select apparently. I can now cause it to fail by adding the class to the span in the browser inspector. First of all, I don't understand why the span fails simply because it is given a class of 'select2'. Second, I don't know where that class is coming from. Displaying the form alone doesn't have that class. It only shows up when crispy displays it, and they say that they aren't adding it.
The outer span:
<span role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-id_member-container" class="select2-selection select2-selection--single">
<span class="select2-selection__rendered" id="select2-id_member-container" role="textbox" aria-readonly="true">
<span class="select2-selection__placeholder">Enter a name search here ...</span>
</span>
<span class="select2-selection__arrow" role="presentation"><b role="presentation"></b>
</span>
</span>
Has select2
added:
<span role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-id_member-container" class="select2-selection select2-selection--single select2">
I figured it out, finally. In CrispyFieldNode from templatetags.crispy_forms_field, they set the class_name to:
class_name = widget.__class__.__name__.lower()
So, since the widget is Select2, the class is set to select2, which apparently screws up the javascript. To fix it, I just had to add the following to my settings:
CRISPY_CLASS_CONVERTERS = {'select2':''}
so it doesn't do that. I'm mentioning this just in case someone else might have this issue.
@glennbach It might be worth mentioning this as a crispy-forms issue as its their code that triggers the error. Perhaps they don't have to actually have the .lower()
conversion for their code to work?
I started with an issue in their repo, and they insisted that they didn't add the class (incorrectly). So, I have informed them. It looks like they don't want to do anything about it. At least, if anyone else sees this issue, they have a way to get around it. I wonder if there's any way in your Javascript to survive this situation. Anyway, at least there's a way forward... Thanks!
Grats for getting to the bottom of this !!
Perhaps changing something in DAL would help in any way ?
Maybe patching __name__
unless this would have other (unintended) side effects ?
As for next version: I believe we can prevent any such kind of conflicts with shadow dom enabled web components, so we're really hanging on until then but I will have time available soon to release that with support for both the next model (where your widget generates your view which is auto registered to urls and code is shared) and the current model (where you glue everything yourself).
Currently, only the next model was implemented, but a compatibility is possible for easier (find | xargs sed
based) switch from select2 to the webcomponent in your project.
i don't know enough about your code to have any suggestions, but with a workaround available, it seems that waiting for the next version is reasonable. thanks for a great module!
Yes indeed, and kudos to you for posting the solution ;)
Description:
I'm using this with
django-crispy-forms
. If I just display the plain form with:everything works perfectly. If, I use crispy forms:
then an extra class
select2
is added to the select, which breaks it. Where is that class being added? Can I remove it? Any suggestions? Thanks.Code:
My form:
Actual HTML generated: