Adding SearchInput widget

Hi! I’m wondering if there is any interest in adding a SearchInput widget that would render as <input type="search" ...>?

We already have EmailInput that renders as <input type="email" ...>, URLInput that renders as <input type="url" ...>, and PasswordInput that renders as <input type="password" ...>, so I think it’s a reasonable addition? I would personally find it to be a slight usability improvement to not have to specify the input type in a Form model field like this anymore:

widget=forms.TextInput(
    attrs={
        "type": "search",
    }
),

And instead do:

widget = forms.SearchInput()

Typically Django doesn’t add extra classes only for the sake of completeness with specifications, such as my proposal to fill in the HTTP response code range: [WIP] Fixed #28469 -- Added missing HttpResponse subclasses by adamchainz · Pull Request #8855 · django/django · GitHub .

However, in this case, I’m in favour of adding SearchInput. Widgets have both the class and a corresponding template, so if Django provides them, they are easier for users to override.

Browsers don’t currently style <input type=search> any differently (MDN), but IIUC they’re useful for accessibility… so let’s summon the accessibility team: @accessibility .

2 Likes

All browsers have different behaviours, see the “Differences between search and text types” section on MDN.

Safari also has a different default rendering with rounded corners.

1 Like

Thanks @rik ! (…and welcome to the forum :smile: ). I missed that section - it’s a useful summary, and strengthens the argument for adding a widget to Django.

The main difference I’m aware of is that it’ll get announced as a search field on focus (which is good). There could be others, I am not sure.

If this is the rationale, then we should also have TelInput, RangeInput, and we’ll quickly get to quite niche things like ColorInput and WeekInput, as they all have some extra affordances. How much of that we want to have out of the box rather than let the user create as needed, I’m a little hazy on. I’d be happy to have a few, them all, or none, and document how to create them perhaps.

1 Like

Just out of curiosity, I looked in to how Rails and Laravel handle this.

Rails seems to be on one end of the spectrum, with helpers for an exhaustive list of input types: Action View Form Helpers — Ruby on Rails Guides

Laravel seems to be on the other end of the spectrum, having removed Form helpers from its core codebase. Apparently they thought that writing the form’s HTML manually is straightforward enough, and isn’t worth adding another abstraction: php - Why are Form and HTML helpers deprecated in Laravel 5.x? - Stack Overflow

I see the reasoning in both approaches, but I think I’m of the opinion that somewhere in the middle is the best choice for Django. By offering some more helpers we might be able to introduce new input types to devs who may never have seen them before, and encourage more accessible forms in doing so.

Very open to any other suggestions though.

One problem with being somewhere in the middle is that, for the hypothetical me coming to Django for the first time, I’m left wondering “Why are only some fields covered? Is there something I’m not understanding about how this works?”.

Now, the solution might be a note in the docs like “hey, we don’t cover the exhaustive list of all possible input types, just the most commonly-used”.

On the other hand, “commonly-used” might leave out some subset of devs who use ColorInput or whatever all of the time.

On the other other hand, maybe just adding the widgets isn’t a lot of code and the maintenance burden is low and it makes it apparent to new users that they’re not missing anything.

1 Like

Yeah, I would say that is Django’s general approach: provide the useful core, and ways to extend to all use cases.

I think whatever we do, a section on making custom widgets at the bottom of the widgets docs would be a great addition.

The debate still remains on where to draw the line on including SearchInput and the other widgets.

One other argument for including more field types is for form template packs, such as those used by django-crispy-forms. If a widget class exists, it has a corresponding template, and a form template pack can override it. Widgets left to the user don’t have predictable template locations, so a template pack can’t override them—except by providing the widget class too.

+1, discoverability is important.


I am now leaning towards a policy like “widgets for all <input> types with decent cross-browser support”. So that would mean color (shows a colour picker on most browsers) but not week (MDN: “cross-browser support is currently a bit limited, with only Chrome/Opera and Microsoft Edge supporting it at this time.”).

1 Like

Very good points. I like the “provide widgets for all input types with decent cross browser support” a lot. I agree that the maintenance burden seems low, so we might as well provide as many reasonably useful ones as we can.

I’m away from a computer for another ~10 days and I’m not sure what next steps look like for Django, but once I’m back in front of a keyboard I can write up what we discussed into a ticket and start work on implementing the widgets?

I am now leaning towards a policy like “widgets for all <input> types with decent cross-browser support”. So that would mean color (shows a colour picker on most browsers) but not week (MDN: “cross-browser support is currently a bit limited, with only Chrome/Opera and Microsoft Edge supporting it at this time.”).

I quite like this suggestion. My only concern is that we need to monitor this, but that is the case for a lot of things already when dealing with browser support and not a big issue. I also think that week is very uncommon, even compared with color which is often used for theming and customisation.

I also don’t have much concern about these spiralling out of control as these fields do not change much. While I do see some conversations around e.g. adding alpha channel and colorspace support to color fields, this and all HTML changes are glacial enough that it’s not something I think we should worry about.

So yes, broadly agreed.

I’ve looked into all the input types listed on MDN, and come up with the following. I’ve linked a short explanation of my decision for each input type not currently in Django below the summary table.

tldr; we should add widgets for <input type=...>

Adding date, datetime-local, and time would likely require a breaking change to existing widgets, so I decided to not add those for the purposes of this thread. Could be another discussion for the future though.

Summary

Input Type In Django already? Should it be? Add it!
button :x: :x: :x:
checkbox :white_check_mark: :white_check_mark: :x:
color :x: :white_check_mark: :white_check_mark:
date :x: ? :x:
datetime-local :x: ? :x:
email :white_check_mark: :white_check_mark: :x:
file :white_check_mark: :white_check_mark: :x:
hidden :white_check_mark: :white_check_mark: :x:
image :x: :x: :x:
month :x: :x: :x:
number :white_check_mark: :white_check_mark: :x:
password :white_check_mark: :white_check_mark: :x:
radio :white_check_mark: :white_check_mark: :x:
range :x: :white_check_mark: :white_check_mark:
reset :x: :x: :x:
search :x: :white_check_mark: :white_check_mark:
submit :x: :x: :x:
tel :x: :white_check_mark: :white_check_mark:
text :white_check_mark: :white_check_mark: :x:
time :x: ? :x:
url :white_check_mark: :white_check_mark: :x:
week :x: :x: :x:

Justifications

button

Should not add. MDN discourages their use:

While <input> elements of type button are still perfectly valid HTML, the newer <button> element is now the favored way to create buttons.

color

Should add. Decent browser support as discussed above.

date

Should not add, but unsure. DateInput widget exists in Django already, but is rendered as type="text". Not sure if updating this widget to this input type is worthy of a breaking change.

datetime-local

Should not add, but unsure. DateTimeInput widget exists in Django already, but is rendered as type="text". Not sure if updating this widget to this input type is worthy of a breaking change.

image

Should not add. While well-supported, seems extremely niche:

<input> elements of type image are used to create graphical submit buttons, i.e. submit buttons that take the form of an image rather than text.

month

Should not add. Patchy browser support:

The control’s UI varies in general from browser to browser; at the moment support is patchy, with only Chrome/Opera and Edge on desktop — and most modern mobile browser versions — having usable implementations.

range

Should add. Similar to color, there is good browser support.

reset

Should not add. MDN discourages their use:

You should usually avoid including reset buttons in your forms. They’re rarely useful, and are instead more likely to frustrate users who click them by mistake (often while trying to click the submit button).

search

Should add. As discussed above, useful for accessibility and other reasons.

submit

Should not add. Their behaviour is more like a button than a form input element.

tel

Should add. There are benefits to using this type despite being functionally equivalent to type="text":

Despite the fact that inputs of type tel are functionally identical to standard text inputs, they do serve useful purposes; the most quickly apparent of these is that mobile browsers — especially on mobile phones — may opt to present a custom keypad optimized for entering phone numbers. Using a specific input type for telephone numbers also makes adding custom validation and handling of phone numbers more convenient.

time

Should not add, but unsure. TimeInput widget exists in Django already, but is rendered as type="text". Not sure if updating this widget to this input type is worthy of a breaking change.

week

Should not add. As discussed above, patchy browser support.

On the phone so won’t find it now but (on Django-developers, if not again here) there have been various threads about adding support for date inputs.

The consensus has been that each time it’s been looked at the cross browser support wasn’t there, and we weren’t sure about handling migrations for folks who’ve already done other things. But pending the first improving, likely the second could be addressed. (So question is largely, when, if ever, is it good enough? E.g. Is input type="date" ready for use in accessible websites? - Hassell Inclusion)

HTH.

1 Like

Thank you, indeed very helpful! This is one of the Django-developers conversations that links to other ones.

And this ticket on documenting how to use DateInput with input_type='date' seems quite reasonable. Perhaps added documentation is the best solution for now.

As always, date/time is a beast of a problem.

1 Like

Noting other relevant tickets:

@claudep would you have any feedback on the above? I’m triaging the newly created tickets and I have found some commentary from you from 11 years ago that I’d like to take into consideration before continuing.

I think that the main things that have changed since then are:

  • the accessibility concerns/benefits that specialized widgets bring to the table
  • the increased wide browser support
  • the mentioned discoverability aspect

In general I’m in favor of adding at least SearchInput and ColorInput, with a less clear preference for TelInput (but why not) and doubts for RangeInput following something that @sarahboyce mentioned (how would a RangeInput relate to a Postgres’ specific RangeField?).

<input type=range> is poorly named. It does not represent a range (or interval) but rather a numerical value within a range. So it would be stored in an IntegerField or DecimalField or FloatField.

Given this “awkwardness”, I feel inclined to then not have a RangeInput in Django (but yes to Search, Color and Tel).

I don’t think the names clashing between HTML and PostgreSQL are a valid reason to keep this particular type out of Django. Finding a name that helps avoid the confusion might be tricky though. Maybe WithinRangeInput (keeps “range” to keep it connected to HTML) ?

I’m a bit Meh too TBH. I can’t see that I’d ever consciously switch to the widget when a regular one with max/min validators would do.

That is, I think it might see very low usage, such that it would be better for folks to define it themselves if they really wanted. In lots of areas, DB functions say, we provide the common cases, leaving users to fill the more niche gaps. I’d lean toward similar here.

I’m fine with leaving range out, as I agree that usage would be low.

If I was ranking usefulness of the remaining three, I think search would be my definite winner, while color and tel would come in a distant second/third. But still useful to include in core for accessibility/discoverability/othe reasons discussed above imo.