Elixir列表理解中的表单输入

时间:2016-12-08 15:41:47

标签: forms elixir phoenix-framework

我正在显示一个学生表,并希望每一行都有一个表单元素,可用于更改该学生的信息。我目前拥有的内容(如下所示)仅适用于表格中的最后一位学生,因为:manual_choice:student_id在行与行之间不是唯一的表单字段。

如何让所有学生对此列表进行理解,为表格的每一行生成唯一的表单字段,以便在提交表单时,我可以更新为其选择了manual_choice的学生?

<%= form_for @changeset, assignments_path(@conn, :manual_assign), fn f -> %>
<table id="students" class="display" cellspacing="0" width="100%">
  <thead>
    <tr>
      <th>Student Name</th>
      <th>Assigned Project</th>
      <th>Override Assignment</th>
    </tr>
  </thead>
  <tbody>
    <%= for student <- @all_students do %>
      <tr>
        <td><%= student.student_name %></td>
        <td><%= student.assigned_project %></td>
        <td class="text-right">
          <div class="form-group">
              <%= select f, :manual_choice, @projects, class: "form-control", id: "manual_choice" %>
              <%= text_input f, :student_id, class: "form-control", value: student.id, style: "display:none" %>
          </div>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>
<% end %>

1 个答案:

答案 0 :(得分:0)

正如受人尊敬的Dogbert指出的那样,维护成本较低的方法是为每个学生记录创建一个单独的表格;单击提交按钮将仅提交该记录的数据。

但是如果您特别想要一个底部有一个提交按钮的巨型表(更适合某些批量更新情况),也许您可​​以在每个输入的名称中包含一个递增的计数器。一个简单的例子可能如下所示:

<%= @all_students |> Enum.with_index |> Enum.each(fn(student, index) -> %>
  ...
    <%= select f, "student_#{index}[manual_choice]", @projects, class: "form-control" %>
    <%= text_input f, "student_#{index}[id]", value: student.id, style: "display:none" %>
  ...
<% end %>

注意:

  1. 我使用Enum.with_indexEnum.each来迭代学生列表,而不是for student <- @students。我来自Ruby世界,其中for循环不受欢迎;我发现我可以随时使用Enum.eachEnum.map,我还不需要使用for构造。
  2. 对于选择&amp;输入元素,我提供了一个对每个元素都是唯一的字符串。例如,第五行的选择名称应为student_4[manual_choice]
  3. 我没有测试过这一切;我只是吐鬼。我相信这种通用方法可以很好地工作,但不清楚确切的语义。例如,我不知道Enum.each是否会实际打印出任何生成的标记/内容; Enum.map可能会更好。
  4. 接收提交表单的控制器端点必须能够理解参数并迭代每个学生的表单数据。我怀疑这很简单(在Rails世界中它非常容易)但是在Elixir / Phoenix中还没有这样做。
  5. 如果#4给你带来麻烦,也许更简单的方法是使用数组语法命名每个输入元素,例如:"students[manual_choice][]""students[id][]"。这样,在控制器操作中,您可以迭代students[id]嵌套的参数,并相信每个条目都对应students[manual_choice]的相同索引。