why

why

Liveview and onBeforeElUpdated

Hello,

I like the idea of using a local js helper library like alpinejs when working with Liveview. I find it very useful for simple things like menu open/close where higher latency might be a tad too noticeable when solved in Liveview. What’s particularly nice is that I keep the ability to “liveview update” content inside an element opened via alpine.

Conveniently, support for libraries like alpinejs was added in Liveview a little while ago, documented here. To get to the relevant subsection, one needs to search for the paragraph that contains “onBeforeElUpdated”.

Unfortunately, there seems to be a security concern in alpine that makes me shy away from it at the moment. Hoping there will be a solution from the alpine team in the not too distant future, though :slight_smile:

In the meantime, my options seem to be:

  1. Use liveview JS hooks with phx-update=“ignore” for these situations. Works ok, but I lose the ability to “liveview update” content inside ignored elements.

  2. Use liveview JS hooks without phx-update=“ignore” but using the “updated” callback to rescue an open menu after a Liveview update closed it. Am in the process of experimenting with this, the “updated” callback is relatively easy to understand.

  3. Use the onBeforeElUpdated callback mentioned above like alpine does. Unfortunately, I can’t quite figure out how to use that, and was wondering if anybody might have an example? I’m looking at the morphdom docs at the moment, but it’s slow going…

Thank you!

Most Liked

why

why

I didn’t have any luck with #2, but I ended up settling on #3, and with some experimentation got it to work.

It’s really very simple, the onBeforeElUpdated callback gives you the option to hook into the step when Liveview asks morphdom to update a specific DOM node with some change.

At the onBeforeElUpdated point, morphdom has two versions of the DOM node it is working with: the “to” version (what the node should become) and the “from” version (what the node is at the moment).

If, for example, you want to preserve all the styles in the classList that are there before Liveview wants to push its update, simply set the to.classList to the state of from.classList, like this:

...
dom: {
    onBeforeElUpdated(from, to){
      to.classList = from.classList
    }
  },
...

Important note: It seems like you need to add a unique ID to the node whose classList (or other property) you want to preserve with the above.

The above, is, of course, just a simplification, as you probably want to have some logic to have this happen only on nodes that meet certain criteria. Examples might be only those nodes whose styling is impacted by your local JS helper library, etc.

By the way, playing with this helped me understand how Liveview works much better, and gave me an appreciation for the awesome library that morphdom is :slightly_smiling_face:

You can, for example, see morphdom walking the DOM live, by doing something like this (note that the console.logs slow the process down quite a bit):

...
dom: {
    onBeforeElUpdated(from, to){
      console.log("****************")
      console.log("from state:")
      console.log(from)
      console.log("to state:")
      console.log(to)
    }
  },
...

Hope this helps!

Edit: On further thought, it might be that my problem with #2 was that I didn’t use an ID on the node. It might simply work if you give the node a unique ID…

idi527

idi527

Note that doing

onBeforeElUpdated(from, to){
  to.classList = from.classList
}

would copy the classlist of every patched element over. That might be not what you want since it might revert class changes made via liveview. You’d probably restrict the copying to certain elements only:

onBeforeElUpdated(from, to){
  if (from.classList.contains("before-update-copy-class")) {
    to.classList = from.classList
  }
}

I’ve also settled on that approach in a similar problem Liveview with Muuri grid (would phx-update="stop-ignore" make sense?).

Where Next?

Popular in Questions Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
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
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

Other popular topics Top

New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
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
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement