View Source Phoenix.LiveView.JS (Phoenix LiveView v0.17.7)

Provides commands for executing JavaScript utility operations on the client.

JS commands support a variety of utility operations for common client-side needs, such as adding or removing CSS classes, setting or removing tag attributes, showing or hiding content, and transitioning in and out with animations. While these operations can be accomplished via client-side hooks, JS commands are DOM-patch aware, so operations applied by the JS APIs will stick to elements across patches from the server.

In addition to purely client-side utilities, the JS commands include a rich push API, for extending the default phx- binding pushes with options to customize targets, loading states, and additional payload values.

Client Utility Commands

The following utilities are included:

  • add_class - Add classes to elements, with optional transitions
  • remove_class - Remove classes from elements, with optional transitions
  • set_attribute - Set an attribute on elements
  • remove_attribute - Remove an attribute from elements
  • show - Show elements, with optional transitions
  • hide - Hide elements, with optional transitions
  • toggle - Shows or hides elements based on visibility, with optional transitions
  • transition - Apply a temporary transition to elements for animations
  • dispatch - Dispatch a DOM event to elements

For example, the following modal component can be shown or hidden on the client without a trip to the server:

alias Phoenix.LiveView.JS

def hide_modal(js \\ %JS{}) do
  js
  |> JS.hide(transition: "fade-out", to: "#modal")
  |> JS.hide(transition: "fade-out-scale", to: "#modal-content")
end

def modal(assigns) do
  ~H"""
  <div id="modal" class="phx-modal" phx-remove={hide_modal()}>
    <div
      id="modal-content"
      class="phx-modal-content"
      phx-click-away={hide_modal()}
      phx-window-keydown={hide_modal()}
      phx-key="escape"
    >
      <button class="phx-modal-close" phx-click={hide_modal()}>✖</button>
      <p><%= @text %></p>
    </div>
  </div>
  """
end

Enhanced Push Events

The push/1 command allows you to extend the built-in pushed event handling when a phx- event is pushed to the server. For example, you may wish to target a specific component, specify additional payload values to include with the event, apply loading states to external elements, etc. For example, given this basic phx-click event:

<div phx-click="inc">+</div>

Imagine you need to target your current component, and apply a loading state to the parent container while the client awaits the server acknowledgement:

alias Phoenix.LiveView.JS

<div phx-click={JS.push("inc", loading: ".thermo", target: @myself)}>+</div>

Push commands also compose with all other utilities. For example, to add a class when pushing:

<div phx-click={
  JS.push("inc", loading: ".thermo", target: @myself)
  |> JS.add_class(".warmer", to: ".thermo")
}>+</div>

Using dispatch with window.addEventListener

dispatch/1 can be used to dispatch JavaScript events to elements. For example, you can use JS.dispatch("click", to: "#foo"), to dispatch a click event to an element.

This also means you can augment your elements with custom events, by using JavaScript's window.addEventListener and then invoke them with dispatch/1. For example, imagine you want to provide a copy-to-clipboard functionality in your application. You can add a custom event for it:

window.addEventListener("my_app:clipcopy", (event) => {
  if ("clipboard" in navigator) {
    const text = event.target.textContent;
    navigator.clipboard.writeText(text);
  } else {
    alert("Sorry, your browser does not support clipboard copy.");
  }
});

Now you can have a button like this:

<button phx-click={JS.dispatch("my_app:clipcopy", to: "#element-with-text-to-copy")}>
  Copy content
</button>

The combination of dispatch/1 with window.addEventListener is a powerful mechanism to increase the amount of actions you can trigger client-side from your LiveView code.

Link to this section Summary

Link to this section Functions

Adds classes to elements.

  • names - The string of classes to add.

Options

  • :to - The optional DOM selector to add classes to. Defaults to the interacted element.
  • :transition - The string of classes to apply before adding classes or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - The time to apply the transition from :transition. Defaults 200

Examples

<div id="item">My Item</div>
<button phx-click={JS.add_class("highlight underline", to: "#item")}>
  highlight!
</button>

See add_class/1.

Link to this function

add_class(js, names, opts)

View Source

See add_class/1.

Link to this function

dispatch(js \\ %JS{}, event)

View Source

Dispatches an event to the DOM.

  • event - The string event name to dispatch.

Options

  • :to - The optional DOM selector to dispatch the event to. Defaults to the interacted element.
  • :detail - The optional detail map to dispatch along with the client event. The details will be available in the event.detail attribute for event listeners.

Examples

window.addEventListener("click", e => console.log("clicked!", e.detail))

<button phx-click={JS.dispatch("click", to: ".nav")}>Click me!</button>
Link to this function

dispatch(js, event, opts)

View Source

See dispatch/2.

Hides elements.

Options

  • :to - The optional DOM selector to hide. Defaults to the interacted element.
  • :transition - The string of classes to apply before hiding or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - The time to apply the transition from :transition. Defaults 200

When the show is complete on the client, a phx:hide-start and phx:hide-end event will be dispatched to the hidden elements.

Examples

<div id="item">My Item</div>

<button phx-click={JS.hide(to: "#item")}>
  hide!
</button>

<button phx-click={JS.hide(to: "#item", transition: "fade-out-scale")}>
  hide fancy!
</button>

See hide/2.

Pushes an event to the server.

  • event - The string event name to push.

Options

  • :target - The selector or component ID to push to
  • :loading - The selector to apply the phx loading classes to
  • :page_loading - Boolean to trigger the phx:page-loading-start and phx:page-loading-stop events for this push. Defaults to false
  • :value - The map of values to send to the server

Examples

<button phx-click={JS.push("clicked")}>click me!</button>
<button phx-click={JS.push("clicked", value: %{id: @id})}>click me!</button>
<button phx-click={JS.push("clicked", page_loading: true)}>click me!</button>

See push/1.

See push/1.

Removes an attribute from elements.

  • attr - The string attribute name to remove.

Options

  • :to - The optional DOM selector to remove attributes from. Defaults to the interacted element.

Examples

<button phx-click={JS.remove_attribute("aria-expanded", to: "#dropdown")}>
  hide
</button>
Link to this function

remove_attribute(attr, opts)

View Source

See remove_attribute/1.

Link to this function

remove_attribute(js, attr, opts)

View Source

See remove_attribute/1.

Removes classes from elements.

  • names - The string of classes to remove.

Options

  • :to - The optional DOM selector to remove classes from. Defaults to the interacted element.
  • :transition - The string of classes to apply before removing classes or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - The time to apply the transition from :transition. Defaults 200

Examples

<div id="item">My Item</div>
<button phx-click={JS.remove_class("highlight underline", to: "#item")}>
  remove highlight!
</button>

See remove_class/1.

Link to this function

remove_class(js, names, opts)

View Source

See remove_class/1.

Sets an attribute on elements.

Accepts a tuple containing the string attribute name/value pair.

Options

  • :to - The optional DOM selector to add attributes to. Defaults to the interacted element.

Examples

<button phx-click={JS.set_attribute({"aria-expanded", "true"}, to: "#dropdown")}>
  show
</button>

See set_attribute/1.

Link to this function

set_attribute(js, arg, opts)

View Source

See set_attribute/1.

Shows elements.

Options

  • :to - The optional DOM selector to show. Defaults to the interacted element.
  • :transition - The string of classes to apply before showing or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :time - The time to apply the transition from :transition. Defaults 200
  • :display - The optional display value to set when showing. Defaults "block".

When the show is complete on the client, a phx:show-start and phx:show-end event will be dispatched to the shown elements.

Examples

<div id="item">My Item</div>

<button phx-click={JS.show(to: "#item")}>
  show!
</button>

<button phx-click={JS.show(to: "#item", transition: "fade-in-scale")}>
  show fancy!
</button>

See show/2.

Toggles elements.

Options

  • :to - The optional DOM selector to toggle. Defaults to the interacted element.
  • :in - The string of classes to apply when toggling in, or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}
  • :out - The string of classes to apply when toggling out, or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-100", "opacity-0"}
  • :time - The time to apply the transition :in and :out classes. Defaults 200
  • :display - The optional display value to set when toggling in. Defaults "block".

When the toggle is complete on the client, a phx:show-start or phx:hide-start, and phx:show-end or phx:hide-end event will be dispatched to the toggled elements.

Examples

<div id="item">My Item</div>

<button phx-click={JS.toggle(to: "#item")}>
  toggle item!
</button>

<button phx-click={JS.toggle(to: "#item", in: "fade-in-scale", out: "fade-out-scale")}>
  toggle fancy!
</button>

See toggle/2.

Transitions elements.

  • transition - The string of classes to apply before removing classes or a 3-tuple containing the transition class, the class to apply to start the transition, and the ending transition class, such as: {"ease-out duration-300", "opacity-0", "opacity-100"}

Transitions are useful for temporarily adding an animation class to element(s), such as for highlighting content changes.

Options

  • :to - The optional DOM selector to apply transitions to. Defaults to the interacted element.
  • :time - The time to apply the transition from :transition. Defaults 200

Examples

<div id="item">My Item</div>
<button phx-click={JS.transition("shake", to: "#item")}>Shake!</button>
Link to this function

transition(transition, opts)

View Source

See transition/1.

Link to this function

transition(js, transition, opts)

View Source

See transition/1.