What do you use as an <select> alternative in LiveView?

I guess most people here already know this, but when you have a focused <select> field, LiveView will not update it even if there is updates coming from some event to that specific element.

For example, if you have a <select> element that have an error class, when you select a new value, fixing the error and removing the error class form the assigns, LiveView will keep that class until that <select> is not focused anymore and you do some other update in another field.

For more information about this, you can look into this issue: Select field with focus not updated · Issue #1313 · phoenixframework/phoenix_live_view · GitHub

Now, I was wondering what workaround people are using as a fix for that? In my case I’m changing the <select> id so it will force an update. The problem with that workaround is that the select field will lose focus, so the user experience is affected, specially if you add latency to the mix.

I thought about maybe just ditching the <select> and use <li> <ul> with some css and a JS hook to replicate a <select> field without the same limitations. Did someone already tried that and can give a feedback?

What other solutions do you know for this specific case?

4 Likes

Thanks for posting this. I was actually fighting hard against this problem some weeks ago and wondering if it’s only me… In my case, when a user select an item, they can optionally edit it by clicking a button that opens an editor in a modal. After they close the modal, the name of the element in the select might need to be changed, and that doesn’t work by simply updating the assigns.

In the end, out of frustration, I opted for the brute-force solution: I send an event to the front-end, and update the select from an event listener (added with window.addEventListener). Would love to use something more elegant.

I hear ya! I also spend a lot of time trying to debug this and wondering where exactly I was messing up…

It would be great if the documentation at least was more clear about some gotchas like this one and would give some possible solutions (if there is, I couldn’t find it…).

We use GitHub - maxmarcon/live_select: Dynamic (multi)selection field for LiveView

1 Like

Hi @sezaru - the Phoenix team are dedicated to providing the best possible documentation, so feel free to either add an issue or PR to the GitHub repo if you experience frustration that better docs could fix. PS - I’m not a team member - I just look at the issues & PRs from time to time.

2 Likes

I haven’t used LiveView or Elixir for a while, but could you just add a wrapping element for select element and add error class to it instead that would style select underneath?

Sure, I could do that, but I would like to have confirmation first that this is actually needed, otherwise I would just do a PR to be denied.

Maybe I’m reading too much into it, but the fact that the issue is closed for me means that this is not something that the devs see as a bug in LiveView, but probably just a necessary behavior since there are actually bugs in a browser that would not allow having the focused feature work.

I’m not sure this would fix it, I didn’t test. But I believe it probably won’t, and there are other problems that this case, the error class one is just one of them.

For example, another issue that I found with this is that if you have another select that is dependent on that one updating, then that will not always work, it will depend on how much latency you have.

I didn’t test

Then you should test it because problem in your case is that LiveView is not updating the element because it’s focused input element. Logic says LiveView should still update the wrapping element because it’s not a focused input element.

For example, another issue that I found with this is that if you have another select that is dependent on that one updating, then that will not always work, it will depend on how much latency you have.

You could use the id change trick here when example select-1 value is changed and you have related select-2 then change select-2’s id when select-1’s value is changed. But this could lead to potential lose of focus if you focus on select-2 before update comes back from the server. Maybe it’s indeed better to use some other element to create similar functionality instead of select if you have related selects but original issue should be fixable with a wrapping element.