trisolaran

trisolaran

Hi! :waving_hand:

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.

demo

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 :wink:

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 :folded_hands:

Thanks,
Max

Hexdocs

https://github.com/maxmarcon/live_select

Showing Posts 1 to 10

zachallaun

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

TwistingTwists

ivanminutillo

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

trisolaran OP

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 :+1:

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:

<%= live_select form, field, options %>

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):

<.live_select form={form} field={field} options={options} let={{label, _value}}>
  <div><%= String.upcase(label) %></div>
</.live_select>

So the answer to your question is: “probably yes”.

I’m interested in any thoughts you might have

trisolaran

trisolaran OP

Hi @TwistingTwists and thanks.

The LiveSelect component 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:

<%= live_select form, :user_role %>

This will render 2 inputs: a visible text input called :user_role_text_input and a hidden one called :user_role

If 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_role and :user_role_text_input will have the same value.

Hope this makes sense

trisolaran

trisolaran OP

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 :slight_smile:

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

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

milangupta

This is awesome !! Thank you.
A couple of suggestions if I may ..

  1. commenting out the phx-change on the component (component.html.heex) allows for the event to fire. For some reason, I was not seeing the handle_event triggering (only the handle_info callback).
  2. a bit of a hack, but I needed to have three LiveSelect components on the same form with “intelligence” i.e. the search criteria and the options displayed were interdependent. Hence, I needed the values of all three components passed into handle_info (for determining the options to display) when any of them changed. This is similar to the “grouping” function of checkboxes and how the values are passed into liveview callbacks. I was able to accomplish this with a few tweaks .. basically, am using the handle_event to collect the key value pairs as all form component values are passed to handle_event upon change. I then pass this back as an assign and onto the LiveSelect component (had to add a “values” attribute in ChangeMsg) which then shows up nicely in the handle_info callback. I can submit the PR on github if you think worthy ..
  3. One side-effect, for handle_events to be generated reliably, I had to also remove the debounce (handle-info always fires).
  4. Do you think it is possible to adapt this so it can work within a live_component ? I am still learning ..

Again, thank you.

trisolaran

trisolaran OP

Thank you @milangupta this is excellent feedback! I’m currently traveling and unable to answer. Expect a proper response over the weekend :+1:

milangupta

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 ?

Where Next? Top

Trending in Announcing Top

wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
restlessronin
The repo is at GitHub - cyberchitta/openai_ex: Community maintained Elixir library for OpenAI API · GitHub. Docs are at OpenaiEx User Gu...
152 11030 135
New
shahryarjb
The Chelekom project is a library of Phoenix and LiveView components generated via Mix tasks to fit developer needs seamlessly. One of i...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
fuelen
Hi all! I want to present a small library which provides a mix task for generating an Entity-Relationship Diagram for Ecto schemas. You...
New

Other Trending Topics Top

mudasobwa
I am seeing a lot of aplications of Argumentum ad Vericundiam in software discussions. They do link some piece of writing and point us to...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New
Herve37
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using. We’re particularly inte...
New
sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New
lawik
I was thinking since Goatmire Elixir turned out pretty good I should maybe do another one. 30th of Sep - 2nd of Oct this year./ The firs...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews