Статьи

Перетаскивание с помощью Rails

Возможность перетаскивания была основой настольных приложений в течение многих лет.
С появлением Ajax, возможность перетаскивания теперь нашла свое применение в веб-приложениях. В этой записи я оживлю созданное нами приложение для ведения блогов с возможностью перетаскивания комментариев в корзину. Это подходящая функция для добавления, так как наши собственные блоги здесь на java.net были подвержены спам-атакам через комментарии, которые требуют очистки.

Настройка вещей

Я собираюсь продолжить с того места, где заканчивается учебник « Использование Ajax с Ruby on Rails» . Однако я буду использовать NetBeans 6.1 и Rails 2.0, поэтому вы можете начать с этой обновленной версии проекта rubyweblog, которая была обновлена ​​до Rails 2.0 (вся серия учебников находится в процессе обновления).

Протестируйте существующий проект rubyweblog

  1. Откройте проект rubyweblog.
  2. Обратите внимание: если вы начинаете с предоставленного проекта rubyweblog, вам также необходимо создать базу данных rubyweblog_development (Run Rake Task> db> create) и запустить миграцию.
  3. Запустите проект и перейдите по адресу http: // localhost: 3000 / posts, чтобы убедиться, что он работает. Добавьте хотя бы одну запись в блоге с парой комментариев.

План

В настоящее время приложение не предоставляет средства для удаления комментария. Теперь я знаю, что в этом приложении отсутствует какая-либо пользовательская модель или административный интерфейс, но я намерен показать, как делать классные вещи с помощью Rails, а не создавать замену роликам , поэтому я сжимаю возможности там, где могу. В этом случае я собираюсь добавить значок мусорной корзины на страницу и позволить пользователям перетаскивать комментарии в корзину для удаления.

Шаг 1. Сделайте комментарии перетаскиваемыми

Здесь мы будем использовать помощник draggable_element , оболочку Rails вокруг объекта Scriptaculous Draggable , чтобы сделать комментарии перетаскиваемыми.

  1. Откройте _comment.html.erb, который является частичным для отображения отдельного комментария, и сделайте его перетаскиваемым, добавив помощник перетаскиваемого элемента в конец файла, как показано ниже жирным шрифтом:
    <% comment_id = "comment_#{comment.id}" %>
    <li id=<%= comment_id %> >
    <%= h comment.comment %><br>
    <div style="color: #999; font-size: 8pt">
    Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
    </div>
    </li>
    <%= draggable_element(comment_id, :revert=>true) %>

    Обратите внимание, поскольку comment_id используется дважды, я вытащил его в локальную переменную, чтобы сделать код немного чище. Возврат возвращает комментарий в его исходное местоположение, если мы уроним его где-нибудь, кроме корзины (которую мы еще не добавили).

  2. Добавьте визуальный индикатор того, что комментарии можно перетаскивать. Откройте scaffold.css (Public> stylesheets) и добавьте следующий стиль:
    #comments {
    cursor: -moz-grab;
    }
  3. Проверьте свои изменения. Комментарии теперь можно перетаскивать, но мы пока не указали, где их можно удалить.

Шаг 2. Добавьте значок корзины

  1. Сохраните (trashfull.jpg) в каталог public / images вашего каталога проекта rubyweblob.
  2. Откройте show.html.erb и добавьте следующий <image_tag> после <text_area> :
    <%= text_area 'comment', 'comment' %>
    <%= image_tag "trash.jpg", :id=>'trash'%>

Шаг 3: сделайте значок корзины получателем

Здесь мы будем использовать помощник drop_receiving_element , обертку Rails вокруг метода Scriptaculous Droppables.add, чтобы дать комментарию пункт назначения удаления и вызвать действие для удаления комментария.

  1. Откройте show.html.erb и добавьте drop_receiving_element в конец файла, как показано ниже:
    <%= drop_receiving_element('trash',                             # The id of the receiving element
    :accept => "comment", # The CSS class of the dropped element
    :with => "'comment=' + (element.id.split('_').last())", # The query string parameters
    :url => {:action=>:trash_comment} # The action to call
    )%>

    Обратите внимание на параметр : with — это фрагмент кода JavaScript, который извлекает идентификатор комментария из идентификатора DOM, который, если вы помните сверху, выглядит как «comment_123». Нам также предстоит проделать определенную работу: во-первых, у нас нет ничего с классом CCS с именем «comment», а во-вторых, нам нужно кодировать действие trash_comment .

  2. Откройте _comment.html.erb и добавьте class = "comment" в тег <li> :
    <li class="comment" id=<%= comment_id %> >
  3. Откройте posts_controller.rb и добавьте следующее действие trash_comment :
      def trash_comment
    comment_id = params[:comment]
    Comment.delete(comment_id)

    render :update do |page|
    page.replace_html "comment_#{comment_id}", ""
    end
    end
  4. Проверьте свои изменения. Перетаскивание комментария в мусорное ведро должно удалить его и удалить его из списка, хотя маркер все еще остается. Это потому, что метод replace_html выше заменяет html внутри элемента маркированного списка. Обтекание маркированных элементов списка в <div> решает эту проблему.
  5. Откройте _comment.html.erb и оберните <li> в <div> , также переместив свойства class и id в <div> :
    <% comment_id = "comment_#{comment.id}" %>
    <div class="comment" id=<%= comment_id %> >
    <li>
    <%= h comment.comment %><br>
    <div style="color: #999; font-size: 8pt">
    Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
    </div>
    </li>
    </div>
    <%= draggable_element(comment_id, :revert=>true) %>

  6. Теперь комментарии должны полностью удалить.

Шаг 4: Добавление визуальных подсказок о том, что происходит

  1. Сохраните (trashfull.jpg) в каталог public / images вашего каталога проекта rubyweblob.
  2. Добавьте пару методов JavaScript в show.html.erb, чтобы поменять источник изображения корзины с пустого на полный и обратно:
    <script>    
    function fill_trash() {
    $('trash').src = "/images/trashfull.jpg";
    }

    function empty_trash() {
    $('trash').src = "/images/trash.jpg";
    }
    </script>
  3. Добавьте пару свойств к drop_receiving_element метода : onHover и : полная:
    <%= drop_receiving_element('trash',                             	  # The id of the receiving element
    :accept => "comment", # The CSS class of the dropped element
    :with => "'comment=' + (element.id.split('_').last())", # The query string parameters
    :url => {:action=>:trash_comment}, # The action to call
    :onHover => "function() {fill_trash()}",
    :complete => "empty_trash()"

    )%>

    Обратите внимание, я не могу сказать вам почему : onHover требует определения функции while : complete принимает любой произвольный JavaScript, но это так.

  4. Проверьте свои изменения. Теперь вы должны увидеть полную корзину для мусора, когда перетащите комментарий поверх нее, а затем снова очистите ее после завершения удаления.
  5. Есть еще одна небольшая проблема — если вы перетащите комментарий на корзину, но на самом деле не удалите ее, ваша корзина останется заполненной. Мы можем исправить это, используя событие onMouseOut . Добавьте его к тегу image следующим образом:
    <%= image_tag "trash.jpg", :id=>'trash', :onMouseOut=>"empty_trash()"%>

    И это должно в значительной степени завершить функциональность перетаскивания. Не забудьте обновить браузер, чтобы получать изменения в Javascript. Кроме того, Firebug — ваш друг, когда вы работаете с Ajax и не видите того, чего ожидаете.

Заполненное заявление

RubyWeblogDND.zip