拖拉记录上下移动--Ajax UI

所谓的 Ajax 拖拉 UI,就是直接用鼠标进行拖拉排序,这种方式对用户来说操作速度更快。

拖拉的 UI 需要额外的前端套件,这里介绍 jQuery UI 的 Sortable Plugin,并直接使用 jquery-ui-rails 这个 gem 来安装

编辑 Gemfile

Gemfile

+  gem 'jquery-ui-rails'

编辑 app/assets/javascripts/admin.js

app/assets/javascripts/admin.js

  //= require bootstrap-datepicker/core
  //= require bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN
  //= require ckeditor/init
+ //= require jquery-ui

编辑 app/assets/stylesheets/admin.scss,其中 .sortable_icon 是给画面中可被拖拉的 ☰ 的样式

app/assets/stylesheets/admin.scss

+  @import "jquery-ui";
+
+  .sortable .sortable_icon {
+   border: none;
+   color: #ECECEC;
+   font-size: 20px;
+   cursor: move;
+   padding-right: 10px;
+  }

执行 bundle,重启服务器

编辑 app/views/admin/events/index.html.erb

app/views/admin/events/index.html.erb

   <table class="table">
+  <thead>
   <tr>
     <th><%= check_box_tag "全选", "1", false, :id => "toggle_all" %></th>
     <th>Event Name</th>
     <th>Actions</th>
   </tr>
+  </thead>
+  <tbody class="sortable">
   <% @events.each do |event| %>
-    <tr>
+    <tr data-reorder-url="<%= reorder_admin_event_path(event) %>">
       <td>
         <%= check_box_tag "ids[]", event.id %>
       </td>
-      <td><%= link_to event.name, admin_event_path(event) %></td>
+      <td>
+        <span class="sortable_icon">☰</span>
+        <%= link_to event.name, admin_event_path(event) %>
+      </td>
       <td>
-        <%= link_to "上移", reorder_admin_event_path(event, :position => :up), :method => :post, :class => "btn btn-default" %>
-        <%= link_to "下移", reorder_admin_event_path(event, :position => :down), :method => :post, :class => "btn btn-default" %>
         <%= link_to "置顶", reorder_admin_event_path(event, :position => :first), :method => :post, :class => "btn btn-default" %>
         <%= link_to "置底", reorder_admin_event_path(event, :position => :last), :method => :post, :class => "btn btn-default" %>
         <%= link_to "Tickets", admin_event_tickets_path(event), :class => "btn btn-default" %>
         <%= link_to "Edit", edit_admin_event_path(event), :class => "btn btn-default" %>
         <%= link_to "Delete", admin_event_path(event), :method => "delete", :data => { :confirm => "Are you sure?" }, :class => "btn btn-danger" %>
     </tr>
   <% end %>
+  </tbody>
   </table>
     <p>
     <%= select_tag :event_status, options_for_select( Event::STATUS.map{ |s| [t(s, :scope => "event.status"), s] }), :class => "form-control" %>
     <%= submit_tag t(:bulk_update), :class => "btn btn-primary" %>
     <%= submit_tag t(:bulk_delete), :class => "btn btn-danger", :data => { :confirm => "Are you sure?" } %>
     </p>
   <% end %>

   <script>
     $("#toggle_all").click(function(){
       if ( $(this).prop("checked") ) {
         $("input[name='ids[]']").prop("checked", false);
       }
     })

+  $( ".sortable" ).sortable({
+    axis: 'y',       // 限制只能上下拖拉
+    items: 'tr',     // 拖拉整个 tr
+    cursor: 'move',  // 变更拖拉时的 icon
+    handle: ".sortable_icon",  // 限制只有点 ☰ 才能开始拖拉,砍掉这行的话,会是整个 tr 都可以进行拖拉,你可以试试看
+    stop: function(e, ui){     // 当拖拉结束时,会调用这个方法
+      ui.item.children('td').effect('highlight', {}, 1000)
+    },
+    update: function(e, ui) {   // 当拖拉结束并且 DOM 上的位置变更时,会调用这个方法
+      reorder_url = ui.item.data('reorder-url')
+      position = ui.item.index()  // 取得顺序
+      $.ajax({
+       type: 'POST',
+       url: reorder_url,
+       dataType: 'json',
+       data: { position: position }
+      })
+    }
+  });
   </script>

设计解说:

  1. 我们将整个 tr 包在 tbody 之中,好让 $( ".sortable" ).sortable 将 tbody 标籤内的 tr 都变成可以拖拉,而不会拖拉到标题列 thead 中的 tr。
  2. 因为每个活动的 reorder 网址都不同,所以我们将网址放在 data-reorder-url="<%= reorder_admin_event_path(event) %> 之中,这样在 jQuery 里面透过 reorder_url = ui.item.data('reorder-url') 就可以取得 Ajax 要送去的网址。

编辑 app/controllers/admin/events_controller.rb

app/controllers/admin/events_controller.rb

  def reorder
    @event = Event.find_by_friendly_id!(params[:id])
    @event.row_order_position = params[:position]
    @event.save!

-    redirect_to admin_events_path
+    respond_to do |format|
+      format.html { redirect_to admin_events_path }
+      format.json { render :json => { :message => "ok" }}
+    end
  end
原文地址:https://www.cnblogs.com/chentianwei/p/9443664.html