Sanjibukai

Sanjibukai

Hi everybody,

For those not yet aware, it’s now possible to bootstrap a Phoenix app with some liveview using the --live flag.
The default sample application seems great as a starter example.

I wanted to play around with this app and I’m still not yet convinced with the No JavaScript part.

For example, currently if I hit the search button without inputting anything yet, we are receiving a flash alert.

For example I modified this code a little so that I receive an info message and without actually running the search on the server.
Very simple modification to do in page_live.ex by adding a pattern matching with an empty query:

# live/page_live.ex
def handle_event("search", %{"q" => ""}, socket) do
  {
    :noreply,
    socket
    |> put_flash(:info, "You must provide something to search.")
  }
end

But I wanted to make the input field automatically focused.
I started by setting an id to the input field so that I can somehow target it and run the JS .focus() function on it.

# live/page_live.html.leex
<input id="search_input" type="text" name="q" value="<%= @query %>"
  placeholder="Live dependency search" list="results" autocomplete="off"/>

The following simple JS code would then do the job

document.getElementById("search_input").focus();

However I’m don’t know how to execute some bit of code within a liveview response.
But I saw that there is now some JS support using hooks.

The problem is that the hook must be set to an element we want to follow. Here since I outputting a message on the flash div, I tried to set a hook there:

# templates/layout/live.html.leex
<p class="alert alert-info" role="alert"
  phx-hook="FocusInput"
  phx-click="lv:clear-flash"
  phx-value-key="info"><%= live_flash(@flash, :info) %></p>

Then I added the following in the Javascript:

// assets/js/app.js
function focusInput() {
  document.getElementById("search_input").focus();
}

let Hooks = {}
Hooks.FocusInput = {
  updated() {
    focusInput();
  }
}
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, hooks: Hooks })

But it doesn’t worked.. Before trying Hooks, I tried to run some JS using an event listener on the phx:update event..
And then I said myself that maybe here the hook on updated() is not when it’s finished but before..
So I tried to put some timeout like so:

// assets/js/app.js
function focusInput() {
  setTimeout(() => { document.getElementById("search_input").focus(); }, 10)
}

And it worked! A little as 10ms did the job.
While I’m not sure why a timeout is necessary I also noticed that it worked only the first time.

The reason is because once the Flash message is displayed, and since the message itself is the same, nothing new is displayed and there is no actual update.

So I added to the flash message a timestamp like:

  |> put_flash(:info, "You must provide something to search #{DateTime.now!("Etc/UTC")}")

And now everything is working.

While I’m convinced that LiveView has huge value. I’m not sure that it could ignore JS in the client side.
There are some kind of very UI oriented things (like focusing inputs, displaying error messages, scrolling the view etc.) that I’m not sure LiveView can do by itself (I mean without running JS code).

Does anyone know how I could do this input focusing task in a better way?

I mean if possible without the timeout and without having to deal with a timestamp.
I don’t try it, but using a dedicated hidden span to receive the timestamp might work..
I’m not sure how to handle HTML within Flash message so I tried to visibility: hidden; and even display: none; on the whole Flash div. And it’s still working because the underlying HTML is still changing.

Showing Posts 1 to 2

chrismccord

chrismccord

Creator of Phoenix

The HTML :autofocus attribution make be enough in this case, but it varies by browser. For your hook, you should be the hook directly on the input, <input id="search" phx-hook="AutoFocus">

Hooks.AutoFocus = {
  mounted(){ this.el.focus() }
}
Sanjibukai

Sanjibukai OP

Hi Chris!
Pleasure to see you here!

The HTML :autofocus will do the job upon first display (and/or first/every mount I guess)..

However in the use case above since I don’t want to put the autofocus right away..
I could have done a bad job explaining the use case, so sorry for the confusion..

But I wanted to apply the autofocus upon a blank search.. I know that an HTML required could do the job as well but, here the main goal for me was to learn how to run some bit of JS (here autofocusing on an input, but it could have be scrolling the page).

And I think that I should set the hook on an element that is actually impacted by a life-cycle event, like an updated..

Since a flash message is displayed, I set it on the flash div..

But I’m even thinking of a dummy display: none; element that can receive (being updated with) some data (literally some text string as inner HTML).

And in that Hook I can consume that data as some command and run arbitrary JS code, which will act like a switch case..

I’m not yet onto channels and live views, but I guess that for sending (and then executing) some JS code, channel might be more suitable..

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews