Generate Form Field(s) for model with Array Model data type

510 views
Skip to first unread message

Arthur Dean

unread,
Jan 2, 2017, 10:56:11 AM1/2/17
to phoenix-talk

I'm using the amazing Phoenix Web Framework and trying to figure out how to create the form field(s) for a model with an array field.

Here is an example field from the model: field :grateful, {:array, :string}

I've tried generating the fields like this:

<%= inputs_for f, :grateful, fn fp -> %> <%= text_input fp, :grateful %> <% end %>

But I get this error: could not generate inputs for :grateful from Motivation.DailyPost. Check the field exists and it is one of embeds_one, embeds_many, has_one, has_many, belongs_to or many_to_many

If I generate the field like this: <%= text_input fp, :grateful %> it generates a form field with a name of: daily_post[grateful] which actually won't work. I would need daily_post[grateful][].

How can I generate a form element for a model with an array datatype? I keep finding answers for nested form fields and relations, but this is a bit different and those solutions do not work.


FYI: This is cross posted on stackoverflow so you can answer the question there if you want to get the points. Here is a link: http://stackoverflow.com/questions/41404526/phoenix-form-field-for-array-model-data-type


Thanks!

Arthur Dean

unread,
Jan 3, 2017, 12:16:33 PM1/3/17
to phoenix-talk
I can override the name parameter in the text_input function to fix the name, add a button that will add and remove form inputs, and then it does save properly but after saving when trying to edit the saved record all array elements are merged into one text input field. How can I split the array elements into multiple form inputs?

Arthur Dean

unread,
Jan 3, 2017, 12:19:51 PM1/3/17
to phoenix-talk
This works, but loading the data after saving does not work. All array values are merged into one input field. 
`  <div class="form-group" id="grateful-group">
    <%= label f, :grateful, class: "control-label" %>
      <%= text_input f, :grateful, name: "daily_post[grateful][]" %>
    <%= error_tag f, :grateful %>
    <input type="button" class="btn btn-success" id="add-grateful" value="add" />
    <script>
      window.onload = () => {
        $('#add-grateful').click((e) => {
          $('<input type="text" name="daily_post[grateful][]" />').appendTo("#grateful-group");
        })
      }
    </script>
  </div>`

Arthur Dean

unread,
Jan 3, 2017, 12:49:58 PM1/3/17
to phoenix-talk
Ok I think I got it now. I still have to add remove buttons and fix a few things but it's pretty straightforward from here. This is what I did:
`defmodule Motivation.InputHelpers do
  use Phoenix.HTML

  def array_input(form, field) do
    type = Phoenix.HTML.Form.input_type(form, field)
    values = Phoenix.HTML.Form.input_value(form, field) || [""]
    Enum.map(values, fn(value) ->
      input_opts = [
        name: Phoenix.HTML.Form.input_name(form, field) <> "[]",
        value: value
      ]
      apply(Phoenix.HTML.Form, type, [form, field, input_opts])
    end)
  end
end
`

I import that file into my web.ex, then I can print array fields like this: `<%= array_input f, :grateful %>`
Reply all
Reply to author
Forward
0 new messages