behe

behe

Phoenix LiveView callbacks - to put text input focus on the selected input field?

I have created a list with items inn LiveView which when an item is clicked is rerendered as an input field. Is there a callback or similar that I can hook into to also be able to put text input focus on the selected input field?

Most Liked

malloryerik

malloryerik

You can also focus an input by using a LiveView push_event if you need the server, or via the LiveView.JS push api without the server by adding JS.dispatch to it. So these are just slightly different flows with slightly different use-cases from the hooks example that @ibarch posted.

From the Server

Push a JS event from a handle_event or handle_input function. You catch your pushed event in either app.js with a window.addEventListener or in a LiveView hook, and then send your changes to the DOM from there.

So that’s something like:

  1. Start with an instigating event, for example a click.
<span phx-click="do_stuff_plus_focus_my_input" ...>Just click it</span> 
  1. Handle it and send a push_event. I’ve called mine focusElementById and sent a little map with the id of the input I want to focus. That map becomes the value for the JavaScript event object’s detail key, as you’ll see in the third step.
 def handle_event("do_stuff_plus_focus_my_input", %{"foo" => bar}, socket) do
    socket = assign(socket, foo: bar)
    {:noreply, push_event(socket, "focusElementById", %{id: "my-input"})}
 end
  1. Now catch that pushed event either from a hook or, as here, from app.js. The id we included (“my-input”) is in the event object as event.detail.id. Then just use standard JS’ .focus() and you’re done.
# app.js 
window.addEventListener(`phx:focusElementById`, (event) => {
  document.getElementById(event.detail.id).focus() 
})

Anyway the push_event docs go over all of this and are probably better written than what I have here.

Client-only Version

I’ve also finally noticed that LiveView.JS has a function called push that lets you compose events that you send from templates. We can use that with JS.dispatch to cut out the server.

  1. JS.push and JS.dispatch in action.
# plz excuse the formatting...
<span phx-click={ JS.push("choose_part_of_speech") 
                  |> JS.dispatch("phx:focusMe", to: "#my-input") 
                }>Click it good</span>

  1. We can grab that event with a window.addEventListener. This is almost the same as with the server, but we’re sending the id name as a string and not in a map, so our JavaScript event object in our listener now has our element ID under target and not detail in a map. So we access the id with event.target.id. Just small differences that keep me in the docs and that I hope will be automated away… You’ll see below.
# app.js
window.addEventListener(`phx:focusMe`, (event) => {
  document.getElementById(event.target.id).focus()
})

And that’s it. It’s all in the docs, but writing things out makes it easier for me to remember.

chrismccord

chrismccord

Creator of Phoenix

Add autofocus to the input tag

maz

maz

And this is the REAL reason why the Native vs. Web war never ends.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48475 226
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127536 1222
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement