Multiple phx-keydown bindings

Hi all

I’m trying to build a custom select with live view and it’s JavaScript interoperability. I started with this example, but I want to do it without Alpine.js (or other client side JavaScript):

Now I’m stuck with the key events:

<button
  type="button"
  class="relative w-full py-2 pl-3 pr-10 text-left bg-white border border-gray-300 cursor-default rounded-md shadow-sm focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
  phx-click={JS.toggle(to: "#option-list-1")}
  phx-keydown={JS.hide(to: "#option-list-1")} phx-key="Escape"
  phx-keydown={JS.show(to: "#option-list-1")} phx-key="ArrowDown"
  >
    <span class="flex items-center">
       <img src={List.first(@options).image} class="flex-shrink-0 w-6 h-6 rounded-full">
        <span class="block ml-3 truncate"><%= List.first(@options).name %></span>
    </span>
    <span class="absolute inset-y-0 right-0 flex items-center pr-2 ml-3 pointer-events-none">
       <svg class="w-5 h-5 text-gray-400" x-description="Heroicon name: solid/selector" xmlns="http://www.w3.>
          <path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 >
       </svg>
    </span>
</button>

The button element represents the select, it shows the currently selected item and when you click it, the dropdown appears.

I also want to make it accessible by keyboard. Adding phx-keydown and phx-key=“Escape” worked as desired, but I cannot add other phx-keydown bindings with other keys.

Is that even possible in Live View?

The documentation is not 100% clear to me:

The onkeydown , and onkeyup events are supported via the phx-keydown , and phx-keyup bindings. Each binding supports a phx-key attribute, which triggers the event for the specific key press.

Does it mean you can add several phx-keydown bindings for different keys or that you can have different keys for one phx-keydown and one phx-keyup?

Kind regards
Daniel

You won’t be able to target multiple keys directly with multiple element bindings because this line will only fetch the first defined key on the element live_socket.js#L482

You’ll have to write a hook that binds a key press listener and do some switch case logic on the event key.

Thanks @03juan for clarifying.