Doing JS events in LiveView

I have used LiveView for personal project, it is POC right now. I like the way it is used, the simplicity of the solution.

Current implementation evaluates only differences in HTML layout. Tags appear only after they are changed.

I needed to update SVG properties for the page, that uses LiveView. They are recalculated after the page is rendered at Front-end, so I have created tag, that triggers this update. SVG is used to inteconnect HTML elements. Initially connections have the length of 0, so they are invisible. JS calculates the proper coordinates and sizes for connections.

When page is loaded the first time, connections are drawn properly. As basic SVG structure is rendered inside LiveView template, connection positions are redrawn on each template update, and the length for each connection is dropped to 0.

So the solution is to update connections after each change in LiveView. This can be done by calling proper JS method. The simplest solution for me is to periodically recalculate connections (though it does not provide smooth animation).

Another way to achieve this, is to force LiveView to rerender JS script tag. Currently, this can be achieved by conditional render. I have observed, that if there will be no changes in final HTML, then JS will not be updated. This means, that to trigger an event inside browser for current LiveView version, script tag needs to be removed, and then added again. To achieve this, script tag needs to appear in a different place of the layout (for example inside the

tag for one render, and outside it for the next one). This causes script to be evaluated.

For my POC, I have created a counter value in assigns, and increment it on each socket update. This value is used to render script tag in different places of the layout.

Also, if you need to trigger some event after LiveView is connected, you can use conditional render and socket.connected? value. When page is rendered on the server (before being passed to client), its value is false, and it becomes true after the client connects to the page. I am using this to trigger initial SVG update, after the socket is connected.

SVG is updated through stimulus.js, so it works Ok, after the page is rendered on the client, but breaks after the LiveSocket is connected (as properties are dropped to their initial values). That’s why I have used the previously described approach.

Update:
So, the basic idea for this solution is:

  • script tag needs to be rendered in multiple places to be evaluated again
  • depending on the required update frequency, browser can use
    • JS setInterval() for recurring updates in the browser, and do not try to call updates from LiveView.
    • Use socket.connected? for conditional templates for triggering action after LiveView is connected the first time.
    • Use some value from assigns (for example counter for continuous updates, or some other property, like boolean value that shows if some value is selected), to render tag in different places.

This solutions are valid now, and possibly better solution will be added in future.

2 Likes