Передача выбранных элементов из jQuery UI Selectable в контроллер Rails - PullRequest
1 голос
/ 11 июля 2011

Я использую Rails 3. A Map имеет и принадлежит многим Collection s, и наоборот.

Что там уже есть ...

У меня есть форма, которая позволяет пользователю выбрать несколько карт, которые будут включены в коллекцию. Для этого я использую пользовательский интерфейс jQuery с методом Selectable в сетке.

Вот как строится сетка:

<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>

Это выглядит примерно так:

Grid example

Когда пользователь завершит выбор, выбранные карты (их тег <li>) будут иметь класс .ui-selected.

Что мне нужно ...

Как я мог передать контроллеру идентификаторы этих выбранных карт , чтобы добавить их в новую коллекцию? А что мне делать в контроллере? Каковы лучшие практики здесь?

Что я думал о том, чтобы делать ...

  1. Я подумал о написании собственного обработчика отправки для формы, который будет проходить через все эти li.ui-selected и каким-то образом пытаться извлечь идентификаторы, затем объединить их в скрытое поле формы и, наконец, отправить форма. Затем в контроллере я снова разделю скрытое поле формы, извлеку идентификаторы и получу Карты из базы данных.

  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-esque?

Ответы [ 2 ]

3 голосов
/ 03 октября 2011

Вот чем я закончил.Это мой 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;
});
0 голосов
/ 11 июля 2011

Сериализация всего на скрытый ВХОД - хороший вариант. Если вам это не нравится, (возможно) более понятный подход заключается в том, чтобы просто сделать вызов AJAX вашему контроллеру; это может даже быть частью обработчика события select на вашем selectable. Это может затем сериализовать выбранные элементы (которые я думаю вы даже получаете в качестве аргумента для события выбора, но я точно забываю и слишком ленив, чтобы найти его) в POST (или GET или PUT ) данные вашего вызова AJAX.

...