django-crispy-forms / crispy-tailwind

A Tailwind template pack for django-crispy-forms
MIT License
329 stars 56 forks source link

DAL Autocomplete not supported #136

Closed VaZark closed 4 months ago

VaZark commented 10 months ago

The autocomplete dropdown is overridden to be a select field with all the choices when using {% crispy form %}

smithdc1 commented 8 months ago

Thanks for the report.

To help me understand your issued could you please provide a small example of your field, the html it's generating and what you would expect it to be.

anorthall commented 6 months ago

I have looked into this a little bit after encountering the same problem. I've tracked the issue down to the fact that a special template for selects exists: templates/tailwind/layout/select.html. This writes the <select> tag manually, which clearly omits any options provided by the widget. These options are how DAL autocomplete works (data-autocomplete attributes, etc.).

The crispy-bootstrap5 template pack does not have any custom select template, and thus works fine with DAL.

I've 'fixed' the issue in my project by replacing select.html with the following:

Old version

{% load crispy_forms_filters %}
{% load l10n %}

<div class="relative">
<select class="{% if field.errors %}border border-red-500 {% endif %}bg-white focus:outline-none border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal text-gray-700" name="{{ field.html_name }}" {{ field.field.widget.attrs|flatatt }}>
    {% for value, label in field.field.choices %}
        {% include "tailwind/layout/select_option.html" with value=value label=label %}
    {% endfor %}
</select>
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
    <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
  </div>
</div>
</div>

New version

<div class="relative">
  {% tailwind_field field 'class' 'bg-white focus:outline-none border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal text-gray-700' %}
</div>

There are obviously some downsides here - you lose the red border for field errors, and the custom styling of select options. Possibly there is also some inconsistency in the way that the classes are hardcoded in this template? I think elsewhere they can be overridden?

I think it's important that widget attributes are passed to the form - it took me quite a while to work out that crispy-tailwind was responsible for this not happening, and it's quite unexpected behaviour in my view.

I did play around with 'fixing' this and also keeping the custom select styling, but initially I've failed as I couldn't see a way to get widget attributes in the select.html template - is flat_attrs context variable only provided to input templates? If so, it looks like adding the select input attributes (outside of using a tailwind_field tag) would not be possible without changes to crispy's core?

I don't know an awful lot about how crispy works and unfortunately I'm a bit short on time right now to read the codebase and figure it out - perhaps someone else knows if widget attrs are made available outside of the base input templates?

Happy to help try and resolve this when I have time if someone can give me some pointers on the above question, or suggest an acceptable solution (is losing the custom styling on select options acceptable?). Thanks for the great package.

anorthall commented 6 months ago

Just an update to the above, I missed that {{ field.field.widget.attrs|flatatt }} is in the 'hard coded' HTML for the <select>. It still doesn't appear to actually pass the attrs though. I will look into it further when I have time.

GitRon commented 6 months ago

@anorthall There is another issue that looks somehow similar: https://github.com/django-crispy-forms/crispy-tailwind/pull/133

It's basically the other way around - options inherit select attributes. Just being curious if those two are connected somehow.

Best
Ronny