trisolaran
LiveSelect - Dynamic selection input component for LiveView
Hi! ![]()
I would like to present LiveSelect, a little library that I wrote to easily add a dynamic selection input to your LV forms.
The idea is that the user can type some text, and the component presents a dropdown with content that is filled dynamically by your LV as the user types (LiveSelect sends your LV a message, and your LV replies with the new list of options). The user can then select an option or continue the search.

Background
There are a few (mostly oldish) tutorials that explain how to build similar components, but to the best of my knowledge no component you can add to your LV as a library and just use.
While creating this component for one of my projects, I put considerable effort trying to get it right, especially handling all the tiny little details like navigation with the arrow keys, selection with mouse or enter key, resetting the selection and so on. Therefore, I decided to make it all available as an easy-to-use library so that hopefully the next poor developer won’t have to reeinvent this wheel ![]()
How to use
To use LiveSelect, you add it to your mix dependencies, import the JS hooks (1-2 lines) into your app.js, and add an extra line in your tailwind configurations. You’re now ready to add the LiveSelect input to your forms.
I would be very happy if at least some folks found this component useful, and I’ll be extremely grateful for any feedback ![]()
Thanks,
Max
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #performance










First 10 of 107 Posts
zachallaun
This looks great! Thanks for releasing it.
Do you have any plans/thoughts about exposing it as a component when LiveView 0.18 hits? Link to new attr syntax (not sure if there’s better docs available as of now).
TwistingTwists
This Looks great. Thanks for releasing it!
https://github.com/maxmarcon/live_select/blob/e59a1c0000c42647956c3e505158fe34f0cd2c1d/lib/live_select/component.html.heex#L16
I am curious, what does this do?
ivanminutillo
This is so great, I was hoping for such effort since a while now.
Does it handle multiselect already, or anyway you plan to implement it?
trisolaran
Thanks @zachallaun !
Interesting, I haven’t been following the development of the 0.18 version that much to be honest, so thank you for the pointer. Looks like LV will soon incorporate some features reminiscent of Surface. I was expecting that and I find it good
To answer your question: my initial idea was to provide an interface as similar as possible to Phoenix.HTML.Forms, because I beleive this is how most people write LV forms:
However, as I mentioned, I would like to make the rendering of the options in the dropdown customizable. The most natural way to do that seems to be using slots, and so I believe I’m gonna have to provide a second interface that uses function components. Let’s say you wanna display all the option labels in uppercase (silly example but just to make the point):
So the answer to your question is: “probably yes”.
I’m interested in any thoughts you might have
trisolaran
Hi @TwistingTwists and thanks.
The
LiveSelectcomponent renders 2 inputs: a visible one where the user enter text and that will contain the label of the option after selection, and a hidden one that will contain the actual value of the option after selection.Let’s say you do this in your form:
This will render 2 inputs: a visible text input called
:user_role_text_inputand a hidden one called:user_roleIf now you pass the options:
%{user: 1, admin: 2, guest: 3}, LiveSelect will render 3 labels in the dropdown:["user", "admin", "guest"]. If you select one of them, the corresponding numeric value (1, 2 or 3) will be the value of the hidden input:user_role, whereas the selected option label (“user”, “admin” or “guest”) will be the value of the text input:user_role_text_input.The label and the values of the options could also be the same of course (i.e. options =
["user", "admin", "guest"]), in which case both:user_roleand:user_role_text_inputwill have the same value.Hope this makes sense
trisolaran
Hi @ivanminutillo and thank you!
you raise a very good point, and I confess I had not given this too much thought until I read your question
I think that a good way to handle multiple selects is to do what this jQuery library is doing:
Basically adding removable tags to the input field as the user selects options.
What do you think?
TwistingTwists
Right on this makes sense.
I’ve had very contrived examples of trying to do the same in Angular in past. This approach is relatively breeze.
Thanks for explaining this one!
milangupta
This is awesome !! Thank you.
A couple of suggestions if I may ..
Again, thank you.
trisolaran
Thank you @milangupta this is excellent feedback! I’m currently traveling and unable to answer. Expect a proper response over the weekend
milangupta
So as I dug deeper into the design, I realized I didn’t need to use handle_event triggered by phx-change at all, so 1 & 3 are not needed. The “grouping” equivalent can be accomplished over the top. Your widget is quite elegant and carefully designed. There is a lot of work that has gone in to make it behave precisely ..
The one thing I struggled with is the interface/integration with the parent - I had to implement a new message to be able to get the “selection” event in the parent. I did not see a way for the parent to determine whether selections had been made.
For complex/tightly integrated interactions, is there an easier way to be able to get to the state of the component i.e. directly accessing variables ?