Inputs_for/4 collection indices

There’s the inputs_for/4 function in Phoenix.HTML.Form. When used with a collection of entities (e. g. for has_many association), it generates indices for each entity’s inputs

<input id="parent_children_0_description" name="parent[children][0][description]" type="text">
<input id="parent_children_1_description" name="parent[children][1][description]" type="text">
[…]

That’s all fine. The question is whether there’s any method of obtaining the current index value that could be used inside template for various purposes (ordinal numbering, different styling depending on the index value, etc.)? Or is “manual” looping and creating all the inputs the only way?

Sounds like you want index from the Phoenix.HTML.Form struct:

  • :index - the index of the struct in the form
2 Likes

I didn’t know about the :index field. Does it give you a numeral index?

Another way to tackle this is to use inputs_for/3 instead of inputs_for/4, which gives you something to work with. For example, you can combine it with Enum.with_index/2 to get an associated index with each Form struct.

<%= for {sub_form, index} <- Enum.with_index(inputs_for(f, :values)) do %>
  <% #see documentation of inputs_for/3 about the hidden inputs you need to create %>
  <%= hidden_inputs_for(sub_form) %>
  ...
<% end %>

With sub_form.index you get exactly that. inputs_for afaik even uses Enum.with_index internally, so no need to duplicate efforts.

The index can be really useful especially if one needs to tack on “add new rows” / “delete existing rows” functionality without needing :ids to exist: Phoenix LiveView form with nested embeds and add/delete buttons · GitHub

3 Likes

Heh - that’s exactly what I need it for :slight_smile:

1 Like

Rather off this thread’s topic but maybe not worth opening a separate one… if you wanted to touch a bit up how those rows appear/disappear (simple fade-in/fade-out would do) what would you suggest?

I‘d start with the liveview JS transition API. It‘s supposed to handle that afaik, but haven‘t used it for something like that.

1 Like

One minor issue I still have… is there a known, “correct” method of focusing newly added inputs? Like the ones in your linked gist?