Building a great select widget
select widget is easy right? We just do this in HTML:
<select name="director"> <option value="george">George Lucas</option> <option value="peter">Peter Jackson</option> <option value="steven">Steven Spielberg</option> </select>
Which gives us:
This works well when there are only a few options. However, when there are lots of options it causes some major issues:
- The user experience becomes quite poor because the user has to scroll through lots of options looking for the right one. We could use a
datalistinstead, which is searchable. However, it doesn't solve our second problem.
The obvious solution is to add a
search field instead:
<input type="search" placeholder="Search" />
Which gives us:
Now the user can just search for what they want, and there's no risk of crashing the web browser with lots of data.
But even this isn't perfect. With a search field you assume that the user knows what they're searching for. And it's a far worse user experience if there are only a few options available - picking an option from a select widget is less effort than searching in this scenario.
We need a widget which works for all cases. If there are only a few options, it should be convenient, and shouldn't require the user to search. But when there are lots of options, we allow the user to search, and it shouldn't crash the web browser.
After much experimentation, we came up with this hybrid widget:
We render a search widget, and when the user clicks on it, we open the hybrid widget in a popup.
The hybrid select widget preloads the first 5 results. This means that for situations where there aren't many options (for example gender) the user immediately clicks on the one they want, and job done.
If they want to see a few more options, they click on load more. And finally, they can just search.
In this way we're able to have a widget which scales well - whether there's two options, or two million options.
The widget is written in Vue JS - the source code is on GitHub. It's available for Piccolo Admin users from version 0.19.1 onwards.
Posted on: 10 Dec 2021
Have any comments or feedback on this post? Chat with us on GitHub.