如果未选中某些复选框,如何提交具有相同名称的多个复选框

时间:2015-09-22 04:26:26

标签: html ruby-on-rails html5

我有一些有趣的情况,我以前从未与Rails打交道(虽然,这确实是一个HTML表单问题)。我有一个表,表中的每一行都有一些表单元素。用户可以根据需要动态添加/删除行,因此表单非常灵活。

<table>
    <tr>
        <%= select_tag .... -%>
        <%= check_box_tag "blah[]", "1", false -%>
    </tr>
    <tr>
        <%= select_tag .... -%>
        <%= check_box_tag "blah[]", "1", false -%>
    </tr>
</table>

我的问题在于复选框。我想为服务器端的复选框获取一组值,当复选框未选中时,我遇到了问题(因为HTML不会发布未经检查的复选框值)。

假设用户检查第一个复选框并且不检查第二个复选框。理想情况下,在服务器端,我会得到

params["blah"] == ["1", "0"]

不幸的是,因为HTML没有发回未经检查的值,所以我得到的是

params["blah"] == ["1"]

我的第一个想法是添加

<%= hidden_field_tag "blah[]", "0" -%>

在每个复选框之前,但当然不起作用。我最终得到了服务器端的以下内容

params["blah"] == ["0", "1", "0"]

隐藏字段总是发回“0”。通常,当您只有一个具有给定名称的复选框时,您将使用隐藏字段技巧。现在它是一个复选框值数组,隐藏的字段技巧似乎毫无用处。

这个问题有优雅的解决方案吗?一个hack是将未选中复选框的值更改为“0”并强制在提交表单时通过JavaScript检查它们。这将确保我在服务器端获得“1”和“0”的有序列表,但似乎必须有更好的方法。

除了JS之外,我唯一能想到的就是重新构建数据发送到服务器的方式。现在我发回几个数组,我希望数组有序(例如,每个数组中的第一个元素保存第1行的数据)。如果我考虑一行并让客户端发送一个大的行列表,它可能会更好。数组中的每个条目都包含行的值。这可能意味着每个复选框都有一个唯一的名称(基于行号),因此值可以汇总到右侧。然后我可以回去使用隐藏的场技巧。 Rails可以轻松地将所有这些转换为行数组(每行有一个数据散列)。但它可能比JS解决方案更多的工作,因为每次添加和删除行时都必须更新表单输入名称属性(这就是我采用当前方法的原因)。

使用复选框是否还有其他技巧可以使我想要做的事情变得容易?

1 个答案:

答案 0 :(得分:1)

使用隐藏技巧解决此问题的一种方法是为每个输入提供一个数字,以便:

<table>
  <tr>
    <%= hidden_field_tag "blah[0]", "0" -%>
    <%= check_box_tag "blah[0]", "1", false -%>
  </tr>
  <tr>
    <%= select_tag .... -%>
    <%= hidden_field_tag "blah[1]", 0" -%>
    <%= check_box_tag "blah[1]", "1", false -%>
  </tr>
</table>

由于它可能有很多字段,使用变量来增加数字会让你头疼。像:

<table>
  <tr>
    <% n = 0 %>
    <%= hidden_field_tag "blah[#{n}]", "0" -%>
    <%= check_box_tag "blah[#{n}]", "1", false -%>
  </tr>
  <tr>
    <%= select_tag .... -%>
    <% n += 1 %>
    <%= hidden_field_tag "blah[#{n}]", "0" -%>
    <%= check_box_tag "blah[#{n}]", "1", false -%>
  </tr>
</table>

发布的参数与您的示例中采用的格式不同(Hash),但您可以使用方法Array将其转换为您想要的.values

 >>> params["blah"]
 # {"0"=>"0", "1"=>"0", "2"=>"1", "3"=>"0"}
 >>> params["blah"].values
 # [0, 0, 1, 0]