water
Capture Keyboard Input(barcode scanner) without input form in Liveview
I’m trying to build a Liveview with 2 parts:
- top:
- switch button: camera / hardware scanner
- show camera scanner
- or empty
- switch button: camera / hardware scanner
- bottom:
- scan history table from db with pubsub: statistics, colors, time,..
When the hardware scanner is used and a scan is made, a sequence of characters is send ending with an Enter-key.
defmodule HelloWeb.ScanLive do
use HelloWeb, :live_view
def render(assigns) do
~H"""
<div phx-window-keyup="scanner">
</div>
"""
end
def handle_event("scanner", key, socket) do
IO.inspect(key)
{:noreply, socket}
end
end
Is this the proper way to do this in Phoenix Liveview using handle_event with keyup?
Can you capture a sequence+Enter at once or do you have to capture separately and build it up.
Most Liked
mcrumm
If you want to capture each key individually, yes.
This requires a form input. I am curious why specifically you wish to avoid this. I can give you a working example (using an ancient Symbol LS1900 barcode scanner to demonstrate
):
Here’s the code:
defmodule HelloWeb.ScanLive do
use HelloWeb, :live_view
def render(assigns) do
~H"""
<form id="form" phx-submit={JS.push("capture") |> JS.push_focus(to: "#input")}>
<input
id="input"
data-count={@count}
type="text"
name="code"
autofocus
phx-debounce="blur"
placeholder="Scan barcode..."
value=""
class="w-full"
/>
<button class="hidden" type="submit">Submit</button>
</form>
<ul>
<li :for={code <- @codes}><%= code %></li>
</ul>
"""
end
def mount(_, _, socket) do
socket = socket |> assign(:count, 0) |> assign(:codes, [])
{:ok, socket}
end
def handle_event("capture", %{"code" => code}, socket) do
IO.inspect(code)
socket =
socket
|> update(:count, &(&1 + 1))
|> update(:codes, &[code | &1])
{:noreply, socket}
end
end
Usually there are (at least) two tricky parts. The first is clearing and re-focusing the input after the form submits. You can use a combination of JS.push() and JS.push_focus() to submit the form and re-focus the input. To ensure the input is cleared after submit, you need to force the input to re-render. In this case I am setting a data-count attribute and incrementing the count on each submit. This will force LiveView to re-render the input with the empty value provided on the element.
The other tricky part is that barcode scanners don’t always send an Enter key as a suffix. I left the phx-debounce="blur" on the input because you will definitely want that if you try to add a phx-change event to the form. Since LiveView won’t re-render focused inputs on change, you would probably want to push an event from the server and use it to reset the input value.
pdgonzalez872
Last Post!
Norman56
For capturing a sequence+Enter at once, I’m not sure if that’s possible. It might be easier to capture the sequence and then add the Enter key as a separate event.
Regarding your issue with the software keyboard popping up, adding inputmode=“none” to the input should fix that.
Popular in Questions
Other popular 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
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









