Реализуйте сортируемые списки ajax с помощью jQuery и Rails 3 - PullRequest
16 голосов
/ 05 октября 2011

Есть много похожих вопросов, но я не могу найти тот, который точно соответствует моим потребностям.

Вы могли бы подумать, что это очень распространенная проблема, и там должны быть полированные решения для драгоценного камня.

Я хочу изменить порядок списка и сохранить положение каждого элемента в базе данных с помощью ajax, очень похожего на список дел в списке в Basecamp. Хотя было бы неплохо иметь возможность перемещать элементы с одного уровня на другой во вложенных списках, мне эта функция вообще не нужна.

Я использую Rails 3.1, jQuery. Было бы целесообразно интегрировать решение с сортируемым плагином jQuery, но я открыт для любых решений.

Если вы не знаете ни одного готового решения, можете ли вы дать мне подсказки о том, как это сделать.

В моих приложениях использовался плагин act_as_category, но он не поддерживается, и я реализовал все остальные функции дерева вручную.

1 Ответ

29 голосов
/ 22 марта 2013

Здесь есть достойный пост в блоге:

был webtempest.com/sortable-list-in-ruby-on-rails-3-almost-unobtrusive-jquery/

По-прежнему показывает на http://web.archive.org/web/20120315004343/http://webtempest.com/sortable-list-in-ruby-on-rails-3-almost-unobtrusive-jquery

По существу:

  1. Внешний интерфейс использует jQuery UI sortable , чтобы разрешить перетаскивание элементов DOM с помощью перетаскивания мышью
  2. Внутренний интерфейс использует acts_as_list для обновления базы данных.

Они оба кажутся достаточно надежными, и я смог реализовать вариацию описанной базовой функциональности, с созданием нового элемента на том же экране и некоторыми CSS 3 наворотами (просто стиль .your-class.ui-sortable-helper соответственно) без особой суеты.Я не проводил тщательного тестирования в разных браузерах, но в WebKit и Firefox он выглядит счастливым.

Пример в блоге на самом деле не слишком сильно использует act_as_list - он просто сериализует идентификаторы объектов с помощью jQuery, а затем перебирает ихв контроллере напрямую - но я думаю, что полезно иметь эти функции на бэкэнде, если вам нужно по какой-то причине автоматизировать изменения оттуда.

Код ключа из сообщения в блоге:

Javascript:

$(document).ready(function(){
  $('#books').sortable({
    axis: 'y',
    dropOnEmpty: false,
    handle: '.handle',
    cursor: 'crosshair',
    items: 'li',
    opacity: 0.4,
    scroll: true,
    update: function(){
      $.ajax({
        url: '/books/sort',
        type: 'post',
        data: $('#books').sortable('serialize'),
        dataType: 'script',
        complete: function(request){
          $('#books').effect('highlight');
        }
      });
    }
  });
});

Представление:

<li id="book_<%= book.id %>">

Сюда входит идентификатор типа book_5, который позволяет $('#books').sortable('serialize') в Javascript создавать параметр запроса, который Rails может анализировать.

Контроллер:

def sort
  @books = Book.all
  @books.each do |book|
    book.position = params['book'].index(book.id.to_s) + 1
  book.save
end

Это может быть неуместно, в зависимости от того, как ваша модель контролируется / контролируется доступ.В моем собственном решении я вместо этого перебрал params['book'] и включил некоторую проверку / обработку ошибок, чтобы гарантировать, что будут приняты только значимые значения.

(PS это очень похоже на подход Райана Бейтсадает его, paywalled, видеокаст на ту же тему.)

(PPS Я знаю, что это старый вопрос, но, как это часто случается со StackOverflow, Google получил меня здесь, поэтому ядумал, что документирую то, что сделал.)

...