Nested Form with Static Labels


I’m trying to create a form that allows people to allocate item quantities between locations. Essentially, a list of available locations (specific to the user) is loaded from the DB, and the form needs to render a list of (location name, number input) pairs to allow users to assign each location a quantity.

My form uses an embedded schema like:

defmodule VirtualStorefrontWeb.CreateItemFormSchema do
  use Ecto.Schema

  embedded_schema do
    field :name, :string
    # Other fields...

    embeds_many :location_quantities, LocationQuantity do
      field :quantity, :integer

I’m not sure how to render the form with the retrieved location names as labels. Things I’ve tried:

  1. Adding a :name field into the LocationQuantity schema, and rendering it using Phoenix.HTML.Form.input_value. This works on initial render, the name disappears as soon as since the on_replace behavior is :delete (:mark_as_invalid and :raise understandably don’t work).

  2. Fetching the list of locations with a stable sort order, and then creating the appropriate number of LocationQuantity’s. I render the view like:

<.inputs_for :let={lq} field={@form[:location_quantities]}>
<div class="flex flex-row"> 
<div><%=, lq.index).name</div>
<.input type="number" field={lq[:quantity]}/>
<% end %>

When it’s time to submit the form, I manually join the list of locations and the list of LocationQuantity’s and create the relevant DB rows. This technically works but it feels super hacky since the location ID isn’t explicitly associated with the quantity, and relies on the sort order.

Just wondering if I’m missing something, or if there’s a recommended way to do stuff like this. Let me know, thanks everyone!

Welcome! It might be helpful to see both schemas and the form. Because there a number of ways to implement a form.