Implementing LiveView edit form for schema with embeds_many

I’m wondering what’s the best way to implement a LiveView form for editing an Ecto schema that has many embeds. Here’s the schema:

defmodule TimeRange do
  # ...
  @primary_key false
  embedded_schema do
    field :from, :time
    field :to, :time
  end
end

defmodule WorkHours do
  # ...
  schema "work_hours" do
    field :date, :date
    embeds_many :hours, TimeRange, on_replace: :delete
  end
end

The UX that I’m after is:

  • the user navigates to the edit form,
  • the form lists all the time ranges for the specified date,
  • each time range has an associated “delete” button that removes it,
  • there are two dropdowns and a button for adding a new time range,
  • on adding a new time range, the form should “normalize” them (make unions of overlapping time ranges, i.e. 9-13 with 10-15),
  • there is a list of 7 checkboxes to repeat the same hours for the following days,
  • everything is saved only when the user hits the “save” button (the current date and the checked dates are updated in the DB).

What’s the best approach to continuously update the data on events (deleting and adding time ranges):

  • use a changeset and call apply_changes each time, get the resulting schema and recreate the changeset for the next render?
  • use a single changeset and modify it via get_change/put_change?
  • work with a form without changeset?

Does it sound like a good place for a custom changeset for this specific form? Where should it live - in the *_web layer?

1 Like

I created a demo live view app a while back that makes heavy use of embeds https://github.com/tfwright/saitama

Basically the approach I used is to include add/remove event handlers for the embedded items.

2 Likes