How to Use JavaScript in a Phoenix LiveView
You can integrate external JavaScript libraries with Phoenix LiveView. This is a slightly complicated process that requires you to work primarily with code across two files.
The first file is your selected LiveView file.
The second file is assets/js/app.js and requires you to write javascript code. This code is called a JavaScript Hook.
Basic Example
In this example, a LiveVIew is created and JavaScript is written to change the elements containing text.
The first step is to create a LiveView. In the render method of the LiveView, you create a DOM element that has an assigned phx-hook property.
defmodule AppWeb.PageLive do use AppWeb, :live_view def mount(_params, _session, socket) do {:ok, socket} end def render(assigns) do ~H""" <div id="box" phx-hook = "Box">BOX TEXT</div> """ end end
JavaScript Hooks
To connect your JavaScript code to your LiveView you need to create a JavaScript Hook. The following instructions show you what a hook is and how to create one using the previous LiveView code.
In assets/js/app.js you will see a LiveView constructor function.
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
Update the code to use a hooks property per the example below. Take notice that after the hooks property is set, a property that has the same name as the phx-hook property (in this case Box) is set. You then set a mounted method and inside it you write DOM code to manipulate the element in the LiveView.
Example
let liveSocket = new LiveSocket("/live", Socket, { params: {_csrf_token: csrfToken}, hooks:{ Box:{ mounted(){ this.el.textContent = "Hello World" } } } })
Local Storage Example
The code below creates an object in local storage that has a single key titled developer and a value assigned to developer. The value of developer is set when a user types into the form. When a user revisits the form, the previous data they entered prepopulates the field.
def mount(_params, _session, socket) do {:ok, assign(socket, developer: "None")} end def handle_event("get_localstorage", %{"developer" => developer}, socket) do {:noreply, assign(socket, developer: developer)} end
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, hooks: { FormLocalStorageHook : { mounted() { this.el.developer.addEventListener("input", (event) => { localStorage.setItem("developer", event.target.value) }) this.pushEvent("get_localstorage", { developer: localStorage.getItem("developer"), }) } }, } })
def handle_event("get_localstorage", %{"developer" => developer}, socket) do {:noreply, assign(socket, developer: developer)} end
<form phx-submit="create-status" phx-hook="FormLocalStorageHook" id={"local_storage_hoook-#{testbed.id}"} > <input value={@developer} name="developer" type="text" /> </form>