zachdaniel

zachdaniel

Creator of Ash

New tools, and a new guide on nested forms with `AshPhoenix.Form`!

Working with nested forms in Ash was already great, but it’s even better now with a the new features that will be in the next release of AshPhoenix! Use hidden checkboxes to automatically add, remove and reorder nested forms!

Also check out the new guide. Inspired by Phoenix & Ecto’s drop_param and sort_param, but with no need to configure a drop_param or sort_param, all automatically handled by AshPhoenix.Form

Example code:

defmodule MyApp.MyForm do
  use MyAppWeb, :live_view

  def render(assigns) do
    ~H"""
    <.simple_form for={@form} phx-change="validate" phx-submit="submit">
      <.input field={@form[:email]} />

      <!-- Use sortable.js to allow sorting nested input -->
      <div id="location-list" phx-hook="Sortable">
        <.inputs_for :let={location} field={@form[:locations]}>
          <!-- inputs each nested location -->
          <div data-sortable="true">
            <!-- AshPhoenix.Form automatically applies this sort -->
            <input
              type="hidden"
              name={"#{@form.name}[_sort_locations][]"}
              value={location_form.index}
            />

            <.input field={location[:name]} />

            <!-- AshPhoenix.Form automatically removes items when checked -->
            <label>
              <input
                type="checkbox"
                name={"#{@form.name}[_drop_locations][]"}
                value={location_form.index}
                class="hidden"
              />

              <.icon name="hero-x-mark" />
            </label>
          </div>
        </.inputs_for>

        <!-- AshPhoenix.Form automatically appends a new item when checked -->
        <label>
          <input
            type="checkbox"
            name={"#{@form.name}[_add_locations]"}
            value="end"
            class="hidden"
          />
          <.icon name="hero-plus" />
        </label>
      </div>
    </.form>
    """
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, form: MyApp.Operations.form_to_create_business())}
  end

  def handle_event(socket, "validate", %{"form" => params}) do
    {:noreply, assign(socket, :form, AshPhoenix.Form.validate(socket.assigns.form, params))}
  end

  def handle_event(socket, "submit", %{"form" => params}) do
    case AshPhoenix.Form.submit(socket.assigns.form, params: params) do
      {:ok, business} ->
        socket =
          socket
          |> put_flash(:success, "Business created successfully")
          |> push_navigate(to: ~p"/businesses/#{business.id}")

        {:noreply, socket}

      {:error, form} ->
        {:noreply, assign(socket, :form, form)}
    end
  end
end

It also comes with very useful tools for manually managing nested forms, when checkboxes just won’t cut it :sunglasses:

def handle_event("add-form", %{"path" => path}, socket) do
  form = AshPhoenix.Form.add_form(socket.assigns.form, path, params: %{
    address: "Put your address here!"
  })

  {:noreply, assign(socket, :form, form)}
end

def handle_event("remove-form", %{"path" => path}, socket) do
  form = AshPhoenix.Form.remove_form(socket.assigns.form, path)

  {:noreply, assign(socket, :form, form)}
end


def handle_event("update-sorting", %{"path" => path, "indices" => indices}, socket) do
  form = AshPhoenix.Form.sort_forms(socket, path, indices)
  {:noreply, assign(socket, form: form)}
end

def handle_event("move-up", %{"path" => form_to_move}, socket) do
  # decrement typically means "move up" visually
  # because forms are rendered down the page ascending
  form = AshPhoenix.Form.sort_forms(socket, form_to_move, :decrement)
  {:noreply, assign(socket, form: form)}
end

def handle_event("move-down", %{"path" => form_to_move}, socket) do
  # increment typically means "move down" visually
  # because forms are rendered down the page ascending
  form = AshPhoenix.Form.sort_forms(socket, form_to_move, :increment)
  {:noreply, assign(socket, form: form)}
end

:partying_face: :hugs: Happy Friday folks! :hugs:

Most Liked

sevenseacat

sevenseacat

Author of Ash Framework

Chapter 8 will cover nested forms - editing an album and all of the tracks for an album in one form. That should be out in a few weeks :slight_smile:

Where Next?

Popular in News & Updates Top

jimsynz
As some of you know, I have been working on a tight integration between Ash and Reactor which has triggered a few small bug fixes in Spar...
New
ConnorRigby
This week we added official Nerves support for the OSD32MP1 line of SOMs. Currently we have tested the osd32mp1-brk breakout board, and ...
New
hugobarauna
Livebook v0.7 is out! This is a major release coming with significant features in the following areas: secret management visual represe...
New
hugobarauna
A new Livebook version arrives this Friday! :tada: As we count down the days, we will share a sneak peek into what’s coming each day thi...
New
sorentwo
Many months ago when I originally announced Oban I mentioned that a LiveView powered UI would be available for it soon. Well, the “soon” ...
New
sorenone
The title doesn’t relay the depth of this announcement, but it is short, balanced, and looked good to us. From open sourcing multiple pac...
New
zachdaniel
Hey everyone! Work is progressing nicely on bulk updates &amp; destroys, which are the primary missing features before I switch to focus ...
New
hugobarauna
Hugging Face is a platform for building, sharing, and collaborating on machine learning applications. This blog post explains how to run...
New
zachdaniel
@jimsynz just launched an epic new extension for Ash! It allows you to create rich mix tasks for calling your resource actions directly f...
New
jjcarstens
Testing code destined for hardware can be tricky, but it just got one tiny bit easier! :tty0tty was just released which is an Elixir por...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42158 114
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
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

We're in Beta

About us Mission Statement