【问题标题】:Pass selected elements from jQuery UI Selectable to Rails controller将选定的元素从 jQuery UI Selectable 传递到 Rails 控制器
【发布时间】:2011-07-11 14:02:38
【问题描述】:

我正在使用 Rails 3。Map 拥有并属于许多 Collections,反之亦然。

什么已经存在...

我有一个表单,允许用户选择几个地图,这些地图将放在一个集合中。为此,我在网格中使用带有 Selectable 方法的 jQuery UI。

这就是网格的构造方式:

<ol id="selectable">
<% for map in @user.maps %>
    <li class="ui-state-default">
        <strong><%= map.title %></strong><br>
        <%= image_tag(map.thumbnail_url) %>
    </li>
<% end %>
</ol>

看起来像这样:

当用户完成选择后,所选地图(他们的&lt;li&gt; 标签)将具有.ui-selected 类。

我需要什么...

我如何将这些选定地图的 ID 传递给控制器​​,以便将它们添加到新集合中?我应该在控制器中做什么?这里有哪些最佳做法?

我想做什么......

  1. 我考虑过为表单编写一个自定义提交处理程序,它会遍历所有li.ui-selected 并以某种方式尝试提取 ID,然后将它们合并到一个隐藏的表单字段中,最后提交形式。然后,在控制器中,我会再次拆分隐藏的表单字段,提取 ID 并从数据库中获取地图。

  2. 另一种方法可能是使用collection_select,它以某种方式与jQuery Selectable 同步。我拥有的collection_select 是:

    <%= collection_select :collection, 
        :map_ids, 
        @collection.user.maps, 
        :id,
        :title, 
        { :selected => @collection.map_ids }, { :class => "map_select", :multiple => true, :size => '10', :name => 'collection[map_ids][]' }
    %>
    

不过,两者听起来都有些骇人听闻。有没有更简单或更 JS/Rails 风格的东西?

【问题讨论】:

  • 我会投票给第一个选项。但是您不必构建带有隐藏字段的表单。只需序列化选择(可能是 JSON)并通过 Ajax 将字符串发送到您的服务器。
  • @Wukerplank 嗯,但是表格的其余部分呢?我也需要提交——除非绝对不可避免,否则我真的不想使用 AJAX。
  • 好吧,序列化到隐藏字段将是下一个最好的事情。这些东西总是让人觉得“hackish”和尴尬。你只需要务实并让它发挥作用。以后总能找到更优雅的解决方案。
  • 我知道我可以让它轻松工作:collection_select 可以在 Rails 中开箱即用,不需要任何控制器修改,但它只是一个基本的多选框。但我喜欢 Rails 和 jQuery 的简单性,而且一定有办法! ;)

标签: javascript ruby-on-rails jquery-ui parameter-passing


【解决方案1】:

这就是我最终的结果。这是我的collection_select

<%= collection_select :collection, 
    :map_ids, 
    @collection.user.maps, 
    :id,
    :title, 
    { :selected => nil },
    { :class => "map_select hiddenElement", :multiple => true, :size => '10', :name => 'collection[map_ids][]' }

这就是我的个人容器的创建方式:

<ol id="selectable">
  <% for map in current_user.maps %>
    <% if @collection.maps.include? map %>
      <li class="singleMapContainer ui-selected">
    <% else %>
      <li class="singleMapContainer">
    <% end %>
      <div class="singleMapInfo">
        <span class="mapId" style="display:none;"><%= map.id %></span>
        <strong><%= map.title %></strong><br>
        <%= map.created_at %><br>
        <%= image_tag(map.thumbnail_url) %>
      </div>
    </li>
  <% end %>
</ol>

这是在提交表单时同步它们的 Javascript:

$("#new_collection, .edit_collection").submit(function(){
  // iterate over each selected map container element
  $("li.ui-selected").each(function(){
    var mapId = $(this).find("span.mapId").html();  // find the map ID
    $("#collection_map_ids option[value='" + mapId + "']:first")[0].selected = true;  // synchronize the multiple select box
  });
  return true;
});

【讨论】:

    【解决方案2】:

    将所有内容序列化到隐藏的 INPUT 是一个不错的选择。如果您不喜欢那个(可以说)更清洁的方法,那就是对您的控制器进行 AJAX 调用;这甚至可能是您的可选择项上的选择事件处理程序的一部分。然后,这可以将所选项目(我认为您甚至将其作为选择事件的参数,但我完全忘记并且懒得查找它)序列化到 POST(或 GET 或PUT) 您的 AJAX 调用的数据。

    【讨论】:

      猜你喜欢
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多