amarandon

amarandon

Calling some JS code upon a LiveView update?

Dear Elixir forum,

We have a web page in which we stream output from processing jobs. We’ve set up LiveView so that the content of our box reflects the current job output. It works great but we’d like to keep the job output in a fixed height box and always show the latest lines (unless the user scrolls up), similar to GitLab CI job output. We’ve got a pure CSS solution but unfortunately because of an old Firefox bug it works only on Chrome.

So we’re wondering if it’s possible to plug a small piece of JS code that would be called when LiveView triggers an update. We could use this code to scroll down the bottom of our output box whenever new content gets appended to it.

Another use case I’m thinking of for being able to call some custom JS code upon LiveView update is when adding items to a list, we could use a piece of JS to highlight the new item in order to make it more noticeable by the user.

Marked As Solved

idi527

idi527

It’s also possible to listen for "phx:update" events which are (at least to my knowledge) emitted when the DOM is done being patched.

https://github.com/phoenixframework/phoenix_live_view/issues/81#issuecomment-473750152

I used it in some of my “experiments” with client side js libs (similarly to LiveView: How to trigger JS function? (Update chart.js on data change)) to create/destroy/recreate their objects when the DOM elements they were “bound” to got “morphdomed”.

Also Liked

peerreynders

peerreynders

Works with thermostat_live.ex:

import css from "../css/app.css";
import "phoenix_html"
import {LiveSocket, debug} from "phoenix_live_view"

let liveSocket = new LiveSocket("/live")
liveSocket.connect()

// grab time and weather temperature from thermostat
// --- assets/app.js --- vvv New vvv

document.addEventListener('phx:update', phxUpdateListener);

function phxUpdateListener(_event) {
  const time = extractTime()
  if (!time) {
    return
  }

  const temperature = extractTemperature()
  if (!temperature) {
    return
  }

  const message =  `${time}: ${temperature}`
  console.log(message)
}

function extractTime() {
  const timeSpan = document.querySelector('div.bar > span')
  return timeSpan && timeSpan.textContent
}

function extractTemperature() {
  const weatherForm = document.querySelector('span.weather form')
  if (!weatherForm) {
     return null
  }

  const result = /[+-]?\d+°[CF]/i.exec(weatherForm.lastChild.textContent)

  return result && result[0]
}

Certainly simpler than using a MutationObserver.

10
Post #4
amarandon

amarandon

Thank you both. The phx:update event did the trick for us. Many thanks.

peerreynders

peerreynders

JS interop is an on-going effort.

So in case there isn’t a suggestion from anyone more familiar with LiveView forthcoming, it may be worthwhile to check out MutationObserver (as already suggested here) in order to run some client code in response to any changes in the DOM.

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> somethi...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
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
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement