Rails hidden_​​field或JavaScript数组以逗号分隔的字符串而不是数组

时间:2017-09-19 18:21:27

标签: javascript jquery ruby-on-rails arrays hidden-field

我过去常常使用collection_select<select>建立<options>

  <%= f.label :members, class: "mdl-textfield__label" %>
  <%= f.collection_select :user_ids, User.where.not(id: current_user).collect, :id, :email, {include_hidden: false}, {:class => "mdl-textfield__input", :multiple => true} %>

后端的帖子很好,看起来像这样:

{"utf8"=>"✓",
 "authenticity_token"=>"redacted",
 "groupchat"=>{"topic"   =>"5dd",
               "user_ids"=>["5","6","7","8"]},
 "commit"=>"Done"}

我想在控制器中使用它的方式:

def groupchat_params 
  params.require(:groupchat).permit(:topic, {:user_ids => []}) 
end

问题:我正在尝试使用无序列表ulli重新创建此功能,因为这是跨平台列表选择器的共识。这就是我所拥有的:

      <ul id="special-select">
        <%= f.hidden_field :user_ids, { multiple: true, value: [] } %>
        <% User.where.not(id:current_user).each do |user| %>
          <li class="groupmember-select" id=<%= user.id %> value=<%= user.id %>>
            <%= user.name %>
          </li>
        <% end %>
      </ul>

我使用JavaScript变量来存储我选择的数组。所有这些都有效,据我所知,这不是问题,我不想把这个问题弄得乱七八糟。我认为是这种情况,因为以下是我的上述.html.erb的脚本:

var user_ids = [];
$("#special-select li").click(function(){
  var index = user_ids.indexOf($(this).attr("value"));
  if (index > -1) {
    user_ids.splice(index, 1);
  }
  else {
    user_ids.push($(this).attr("value"));
  }
  $("#groupchat_user_ids").val(user_ids);
  $(this).toggleClass("selected");
});

当我选择一些项目并在浏览器控制台中查看时,它看起来就像我需要的那样:

> user_ids
["2", "6", "3"]

但是我注意到,当我右键单击浏览器中的对象并粘贴它时,我得到以下内容:

> user_ids
[0: "2", 1: "6", 2: "3", length: 3]

当我使用提交按钮发布上述表单时,我得到以下内容(所有项目都在一个字符串中,以逗号分隔):

{"utf8"=>"✓",
 "authenticity_token"=>"redacted",
 "groupchat"=>{"topic"   =>"5dd",
               "user_ids"=>["5,6,7,8"]},
 "commit"=>"Done"}

我已经尝试JSON.stringify(输出未更改,看起来与上面相同)和JSON.parse(几乎像我需要的那样,但是在后端的POST中可以看到转义的引号,无论如何没有工作。

之前我遇到过一个非常类似的问题,但是在我:user_ids默认为数组之前。

任何见解都会很棒!

1 个答案:

答案 0 :(得分:1)

您只能通过一个隐藏字段传递数组。您需要做的是添加多个具有相同名称的隐藏字段。生成的HTML应如下所示:

<input value="1" multiple="multiple" type="hidden" name="groupchat[user_ids][]">
<input value="2" multiple="multiple" type="hidden" name="groupchat[user_ids][]">
<input value="3" multiple="multiple" type="hidden" name="groupchat[user_ids][]">

因此,您不需要将val更改为数组,而是需要创建多个隐藏标记,并通过javascript跟踪它们。

您可以在正在使用的data-hidden-field-tag元素上使用li属性,并将其存储以代替user_ids数组。在表单中有一个id hidden-fields div或任何你想要的div,并且每次有变化时都用隐藏字段更新div。

编辑:根据您的应用程序添加代码。

HTML部分。

<div id="hidden-fields" style="display: none;"></div>
<ul id="special-select">
  <% User.where.not(id: current_user.id).each do |user| %>
    <li class="groupmember-select" id=<%= user.id %> value=<%= user.id %> data-hidden-field-tag="<%= html_escape_once f.hidden_field(:user_ids, { multiple: true, value: user.id }) %>" >
      <%= user.identity %>
    </li>
  <% end %>
</ul>

Javascript部分:

var selectedUsers = [];
$("#special-select li").click(function(){
  var index = selectedUsers.indexOf($(this).attr("data-hidden-field-tag"));
  if (index > -1) {
    selectedUsers.splice(index, 1);
  }
  else {
    selectedUsers.push($(this).attr("data-hidden-field-tag"));
  }
  $("#hidden-fields").html(selectedUsers);
  $(this).toggleClass("selected");
});