Phoenix Framework - Как заполнить поле карты через form_for?

Я пытаюсь заполнить поле :params (из модели/схемы), которое является картой. У меня есть рабочая форма form_for, и я хотел бы заполнить эту карту :params с помощью флажков, чтобы при отправке формы контроллер получил что-то вроде %{... params => %{"param1" => "true", "param2" => "false"}} ...

Я просмотрел inputs_for, но, похоже, это не то, что мне нужно, поскольку оно основано на вложенных схемах и моделях, и это означало бы, что мне нужно создать новую схему для каждого нового набора параметров (мне нужно что-то общее, что не требует внесения изменений в исходный код при изменении параметров).

<%= form_for @changeset, audit_audit_path(@conn, :new_tool_request, @audit.id),
       fn f -> %>

  <%= render LayoutView, "changeset_error.html", conn: @conn, changeset: @changeset, f: f %>

  <div class="form-group"><label>Tool</label>
    <%= select f, :toolname, tools %>
  </div>
  <div class="form-group"><label>Parameter 1</label>
    <%= checkbox f, :param1 %>
  </div>
  <div class="form-group"><label>Parameter 2</label>
    <%= checkbox f, :param2 %>
  </div>

  <div class="form-group"><label>Date of Execution</label>
    <%= datetime_select f, :date %>
  </div>
  <div class="form-group">
    <%= hidden_input f, :audit_id, value: @audit.id %>
  </div>

  <%= submit "Request", class: "btn btn-primary" %>
<% end %>

Так что вместо этих флажков для param1 и param2 мне нужно перенести все эти параметры на карту. Если отображается другая форма с другими флажками для параметров, она должна заполняться без какой-либо связи со схемой.

Спасибо!


person Sasha Fonseca    schedule 20.01.2016    source источник
comment
Если я правильно понял ваш вопрос, я думаю, вам просто нужно создать атрибут имени с параметрами пространства имен для них, поэтому что-то вроде <%= checkbox f, :param1, name: "params[param1]" %> и <%= checkbox f, :param2, name: "params[param2]" %>, но я считаю, что с form_for это должно быть сделано автоматически.   -  person NoDisplayName    schedule 20.01.2016
comment
Это было не совсем то, что я хотел, но это работает! Спасибо. Просто для справки: если вы сделаете то, что предложил @JustMichael, вы отправите другую форму/карту, в данном случае с именем params. В вашем контроллере просто определите функцию, которая получает такие параметры, как def action_to_use(conn, "form" => form, "params" => params, и вы получите вторую форму, которую вы создали с пространством имен.   -  person Sasha Fonseca    schedule 20.01.2016


Ответы (2)


На самом деле, я думаю, если в такой ситуации:

  schema "checkmapss" do
    field :name, :string
    field :options, :map

    timestamps()
  end

Нам просто нужно сделать это в form.html.eex:

  <div class="form-group">
    <%= label f, :options, class: "control-label" %>
    <%= text_input f, :options_one, name: "checkmap[options][one]", class: "form-control" %>
    <%= error_tag f, :options %>
  </div>
  <div class="form-group">
    <%= label f, :options, class: "control-label" %>
    <%= text_input f, :options_two, name: "checkmap[options][two]", class: "form-control" %>
    <%= error_tag f, :options %>
  </div>

Затем функция набора изменений поможет нам закончить другую вещь.

person Bingoabs    schedule 16.03.2017

Я столкнулся с той же проблемой, но с простыми HTML-формами и эликсиром сопоставление экто-шаблонов заставило его работать красиво и легко.

Определение экто-схемы

schema "stuff" do
  field :name, :string
  field :settings, :map
end

Контроллер или ресурс :edit действие

changeset = StuffContext.change_stuff(stuff)

В вашем шаблоне/форме

<%= form_for @changeset, Routes.stuff_path(@conn, :save, @stuff), fn f -> %>
   ...
   <%= label f, :currency %>
   <%= text_input f, :stuff_currency, name: "stuff[settings][currency]", 
   value: @stuff.settings["currency"], required: true %>
   <%= error_tag f, :settings %> <-- Important errors come from ecto validation logic we put into changeset, not the made up currency
   ...

Затем в вашем контроллере :save действие

def save(conn, %{"id" => id, "stuff" => stuff_params}) do
  stuff = StuffContext.get(id)
  ...
  IO.inspect(stuff_params) ->

  %{"name" => "welcome", "settings" => %{"currency" => "USD"}}
  ...
  StuffContext.update_stuff(stuff, stuff_params)
person Yuxel    schedule 10.03.2021