Is there a way to use tom-select.js with LiveView?

Is there a way to use https://tom-select.js.org with LiveView?
I tried it out, but the <select> element that I tried to affect is not modified at all… nothing seems to happen. Am I missing anything?

Thanks!

Yea, you can setup a hook. See JavaScript interoperability — Phoenix LiveView v0.18.3

do you mean I should figure out something like:

  dom: {
    onBeforeElUpdated(from, to){
      if(from._x_dataStack){ window.Alpine.clone(from, to) }
    }
  }

for the tom-select lib?

They mean a hook, which is this part of the page.

https://hexdocs.pm/phoenix_live_view/js-interop.html#client-hooks-via-phx-hook

Here are a bunch of examples. They use Alpine but you can just forget about that part and look at the hook examples

YAY!

The hook works and the multi-select is being rendered correctly. I added phx-update="ignore" to the .input element, otherwise the multi-select would disappear altogether when the form is validated.

Unfortunately, I still haven’t got it right: the form validation turns the multi-select back to its default - plain html - look. I could switch off the form validation, but it does not seem the right thing to do… I’m now trying to use onBeforeElUpdated in this way:

onBeforeElUpdated(from, to) {
  if (from.multiple == true) {
    to = from.cloneNode(true)
  }
}

but the multiselect still gets reset to the plain html version when the form is validated. Any suggestion?

Update:

By checking the generated HTML, it looks like I should rather use this:

to.parentNode = from.parentNode.cloneNode(true)

but it’s still not working.

I solved it by adding phx-update="ignore" in the <div> that wraps the <select> in the CoreComponents’ function def input(%{type: "select"} = assigns) do

Thank you for the help!

I’ve noticed the same. Not sure why the ignore needs to go 1 higher than the actual tag.

If you want a LiveView-native alternative that doesn’t require tinkering with 3rd-party JS libraries, you could try LiveSelect.

If you do, I’d be interested in your feedback.

2 Likes