Opened 4 years ago

Closed 4 years ago

Last modified 20 months ago

#32125 closed New feature (wontfix)

Added basic support for <datalist> elements for suggestions in Input widgets

Reported by: Volodymyr Owned by: nobody
Component: Forms Version: dev
Severity: Normal Keywords: datalist, forms, html5
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: yes

Description (last modified by Volodymyr)

HTML5 introduces a support for <datalist> HTML5 elements for suggestions in input tag

To do this in Django currently, you have to do something like:

django/forms/widgets/datalist.html

{% include "django/forms/widgets/input.html" %}
<datalist id="{{ widget.id }}"{% include "django/forms/widgets/attrs.html" %}>{% for group_name, group_choices, group_index in widget.optgroups %}{% if group_name %}
  <optgroup label="{{ group_name }}">{% endif %}{% for option in group_choices %}
  {% include option.template_name with widget=option %}{% endfor %}{% if group_name %}
  </optgroup>{% endif %}{% endfor %}
</datalist>

django/forms/widgets/datalist_option.html

<option value="{{ widget.value|stringformat:'s' }}"{% include "django/forms/widgets/attrs.html" %}>

django/forms/widgets.py

class Datalist(Select):
    input_type = 'text'
    template_name = 'django/forms/widgets/datalist.html'
    option_template_name = 'django/forms/widgets/datalist_option.html'
    add_id_index = False
    checked_attribute = {'selected': True}
    option_inherits_attrs = False

django/forms/fields.py

class DatalistField(ChoiceField):
    widget = Datalist
    default_error_messages = {
        'invalid_choice': _('Select a valid choice. %(value)s is not one of the available choices.'),
    }

    def __init__(self, *, choices='', **kwargs):
        super().__init__(**kwargs)
        self.choices = choices

Change History (4)

comment:1 by Volodymyr, 4 years ago

Description: modified (diff)

comment:2 by Carlton Gibson, 4 years ago

Resolution: wontfix
Status: newclosed

There was some discussion when adding autocomplete to the admin as to whether to include a datalist widget. (ref #14370 and mailing list discussion.) Perhaps support is better now but, conclusion was more or less that browser support wasn't really good enough to use there.

I'm going to close as wontfix for now. The custom widget is exactly the right way to go.

For an addition like this, I would suggest wrapping it into a small third-party library so that people can try it out and then approaching the DevelopersMailingList to see if there's an appetite to bring such into core. Thanks.

in reply to:  2 comment:3 by Michael, 3 years ago

Replying to Carlton Gibson:

There was some discussion when adding autocomplete to the admin as to whether to include a datalist widget. (ref #14370 and mailing list discussion.) Perhaps support is better now but, conclusion was more or less that browser support wasn't really good enough to use there.

I'm going to close as wontfix for now. The custom widget is exactly the right way to go.

For an addition like this, I would suggest wrapping it into a small third-party library so that people can try it out and then approaching the DevelopersMailingList to see if there's an appetite to bring such into core. Thanks.

Support for it is looking pretty good now: https://caniuse.com/datalist
I think this is going to become more and more necessary. This along with JavaScript modules really makes Django show its age.

comment:4 by Chris Tubbs, 20 months ago

This recently popped up as a need in one of our products. Having the extra option on the TextInput widget or something and copying some of the select widget logic would probably make things pretty simple. Something like:

django/forms/templates/django/forms/widgets/text.html:

{% include "django/forms/widgets/input.html" %}
{% if widget.datalist %}
<datalist id="{{ widget.name }}__datalist">
    {% for group_name, group_choices, group_index in widget.datalist %}
        {% if group_name %}
            <optgroup label="{{ group_name }}">
        {% endif %}
        {% for option in group_choices %}
            {% include option.template_name with widget=option %}
        {% endfor %}
        {% if group_name %}
            </optgroup>
        {% endif %}
    {% endfor %}
</datalist>
{% endif %}

It's nothing too terribly fancy. You'd need to make sure that the widget has {"list": name + "__datalist"} is in the attributes to make sure that that datalist has the right name for the linkage.

You can always go fancier or more robust with it, but something fairly simple that can be tacked onto the standard text widget would be awesome.

Note: See TracTickets for help on using tickets.
Back to Top