# How to add data when dynamically adding inputs using inputs\_for + sort\_param/drop\_param?

**URL:** <https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117>\
**Category:** Questions\
**Tags:** ecto, phoenix, troubleshooting, liveview\
**Created:** [June 11, 2024, 12:21am UTC](https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117 "2024-06-11T00:21:16Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![k-p](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/k/dec6dc/32.png) [@k-p](https://forum.elixirforum.com/u/k-p)\
**Post date:** [June 11, 2024, 12:21am UTC](https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117/1 "2024-06-11T00:21:16Z")

</div>

I’m trying to allow a user to add tags to a parent using a has\_many relationship. I’d like to offer ‘suggested’ tags that they can click and these are added to the form data. These are simple, single, text-entry forms.

I have a dynamic form using inputs\_for with a button to add new, blank, form entries and remove existing values, per the [standard Liveview documentation](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#inputs_for/1-dynamically-adding-and-removing-inputs). I can add new tags, which is a single input, and this works as expected.

How can I programatically add new inputs\_for entries with data in the form entry?

Can I use the value=“new” to set a value I can capture instead?

I’ve tried putting suggested tags as buttons with phx-click and handlers to capture the suggested tag value and put them in the parent struct as a struct item rather than param map, but I can’t work out how to have these render in the inputs\_for in the same way as the ‘new’ tags.

eg, using the example code:

```elixir
<.inputs_for :let={ef} field={@form[:emails]}>
  <input type="hidden" name="mailing_list[emails_sort][]" value={ef.index} />
  <.input type="text" field={ef[:email]} placeholder="email" />
  <.input type="text" field={ef[:name]} placeholder="name" />
  <button
    name="mailing_list[emails_drop][]"
    value={ef.index}
    phx-click={JS.dispatch("change")}
  >
    <.icon name="hero-x-mark" class="w-6 h-6 relative top-2" />
  </button>
</.inputs_for>

<input type="hidden" name="mailing_list[emails_drop][]" />

<button type="button" name="mailing_list[emails_sort][]" value="new" phx-click={JS.dispatch("change")}>
  add more
</button>

```

How could I have a button that would append an `ef` form item with an email value of ‘boop@boop.com’?

---

<div class="post-metadata">

**Author:** ![LostKobrakai](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/32/3072_2.png) [@LostKobrakai](https://forum.elixirforum.com/u/LostKobrakai)\
**Post date:** [June 11, 2024, 7:25am UTC](https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117/2 "2024-06-11T07:25:10Z")

</div>

> [@k-p](#):
>
> How could I have a button that would append an `ef` form item with an email value of ‘boop@boop.com’?

`sort_param` doesn’t support such a usecase. It works from a mapping on a single form key to indexes, so there’s no way to pass any additional data.

The approach taken in [One-to-Many LiveView Form | Benjamin Milde](https://kobrakai.de/kolumne/one-to-many-liveview-form) might work for you.

---

<div class="post-metadata">

**Author:** ![k-p](https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/k/dec6dc/32.png) [@k-p](https://forum.elixirforum.com/u/k-p)\
**Post date:** [June 11, 2024, 12:09pm UTC](https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117/3 "2024-06-11T12:09:58Z")

</div>

> [@LostKobrakai](#):
>
> [One-to-Many LiveView Form | Benjamin Milde](https://kobrakai.de/kolumne/one-to-many-liveview-form)

That link was great and well written. Thanks! Now all working.

The trick in the link above to get the form data and update the changeset in a handler that doesn’t receive the form params, using get\_assoc/put\_assoc, worked great. I can keep all the existing code & behaviour the same, so a neat bonus is still getting deletion of dynamic inputs for ‘free’ from drop\_param.

So to programatically add new inputs with data, you just need a button with a value and one additional handler:

```elixir
 def handle_event("add_tag", %{"value" => tag}, socket) do
    new_tag = %SkillTag{
      tag: tag
    }

    socket =
      update(socket, :form, fn %{source: changeset} ->
        existing = Ecto.Changeset.get_assoc(changeset, :skill_tags)
        changeset = Ecto.Changeset.put_assoc(changeset, :skill_tags, [new_tag | existing])
        to_form(changeset)
      end)

    {:noreply, socket}
  end

```

---

<div class="post-metadata">

**Author:** ![nduitz](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nduitz/32/19627_2.png) [@nduitz](https://forum.elixirforum.com/u/nduitz)\
**Post date:** [December 27, 2025, 10:12am UTC](https://forum.elixirforum.com/t/how-to-add-data-when-dynamically-adding-inputs-using-inputs-for-sort-param-drop-param/64117/4 "2025-12-27T10:12:33Z")

</div>

I know this post is pretty old nevertheless I wanted to share my approach for this.

I use `sort_param` to achieve adding an item of the same type with different configurations.

Here is what I do to achieve this:

```elixir
~H"""
<.inputs_for :let={f} ...>
  <.button name="sort_param[]" value={JSON.encode!(%{attribute: "initial_attribute_value"})}>Add new entity</.button>
  <.input type="hidden" field={f[:_existing_relation]} />
</.inputs_for>
"""

```

Then I use a dedicated changeset function header to handle the add-case

```elixir
def changeset(entity, %{"sort_param" => [initial_attrs]} = attrs) do
  initial_relation_attrs = JSON.decode!(initial_attrs)

  entity
  |> cast(attrs, [])
  |> cast_assoc(:relation, sort_param: :sort_param, with: &MyRelation.changeset(&1, &2, initial_relation_attrs)
end

def changeset(entity, attrs) do
  # handle other change
end

```

An last but not least I use a dedicated changeset function header to handle changing the relation:

```elixir
def changeset(relation, %{"_existing_relation" => _} = attrs, _initial_attrs) do
  # we can ignore initial_attrs for this changeset since this is an existing relation

  ...
end

def changeset(relation, _attrs, initial_attrs) do
  # attrs is always empty when adding, use initial_attrs instead to build the changeset
  ...
end

```

Hope this helps anyone who might find this post later 🙂
