견본 프로그램 (화면 분배 포함) 을 드래그해서 표시 순서를 바꿀 수 있습니다.

13317 단어 Rails

개시하다


데이터 배열 순서를 자유롭게 바꾸려는 요구가 있으면 드래그 앤 드롭을 통해 순서를 바꿀 수 있어 편리하다.
따라서 본고는 Rails4에서 드래그 디스플레이 순서 변경 기능을 실현하는 절차를 소개할 것이다.

보충 자료


나는 이해하기 쉬운 보충 자료를 많이 준비했다.

사이트 제목


히로쿠를 위해 데모 사이트를 만들어 봤어요.
원본 샘플 프로그램은 CRUD를 진행할 수 있지만, 이 아날로그 사이트에서는 데이터를 업데이트할 수 없습니다.(순서만 수정할 수 있음)
드래그 앤 드롭은 어떻게 되는지 실제로 이동해 주세요.

화면 할당


나는 샘플 응용 프로그램을 만드는 과정을 녹음했다.
전스크랩 rails new로 만든 곳부터 시작했어요.
http://www.youtube.com/watch?v=YQ-6HkBhVyc&feature=youtu.be



총 35분 정도니까 보고 싶으면 9분 40초부터 틀어주세요.
그리고 화질이 높아지면 글씨가 변형되지 않아 보기 쉬울 거예요.

소스 코드


샘플 응용 프로그램의 소스 코드가 GiitHub에 업로드되었습니다.
이것도 참고해주세요.

참고 문헌


이 보도는 이쪽의 홈페이지 보도를 각색하여 만든 것이다.

샘플 응용 프로그램의 규격


Scaffold를 사용하여 만든 과일 관리 애플리케이션입니다.
과일 관리 앱도 아니고 단순히 과일 이름을 입력할 수 있는 앱일 뿐이다.
참고로 표시 순서 변경 기능을 설치하기 전의 표 표시는 이렇다.(view는 슬림 사용)
fruits/index.html.slim
table.table.table-bordered
  thead
    tr
      th Name
      th
      th
      th
  tbody
    - @fruits.each do |fruit|
      tr
        td = fruit.name
        td = link_to 'Show', fruit
        td = link_to 'Edit', edit_fruit_path(fruit)
        td = link_to 'Destroy', fruit, data: {:confirm => 'Are you sure?'}, :method => :delete

드래그 앤 드롭을 통해 표시 순서를 수정할 수 있는 기능


이제 설치 단계를 설명합니다.

1. ranked-model gem을 통해 순서 관리


ranked-modelgem을 Rails를 통해 순서를 관리하는 gem로 사용합니다.
acts_as_list도 유명하지만ranked-모델의 성능이 더 좋아요.
다음 순서에 따라ranked-모델을 설치하세요.
Gemfile
+gem 'ranked-model'
$ bundle install
ranked-model에서 Frutt 모델의 정렬 순서를 관리할 수 있도록 합니다.
fruit.rb
 class Fruit < ActiveRecord::Base
+  include RankedModel
+  ranks :row_order
 end
$ rails g migration AddRowOrderToFruits row_order:integer
$ rake db:migrate
fruits_controller.rb
  def index
-  @fruits = Fruit.all
+  @fruits = Fruit.rank(:row_order)
 end
위 코드처럼 roworder 순서에 따라 정렬할 때 rank 방법을 사용합니다.

2. jQuery UI 설치


jQuery UI를 사용하여 드래그 앤 드롭을 수행합니다.
jquery-ui-rails gem을 사용하여 jQuery UI를 설치하는 것이 편리합니다.
Gemfile
+gem 'jquery-ui-rails'
$ bundle install
application.js
+//= require jquery.ui.sortable
참고: 참조 경로는 버전에 따라 다릅니다.
  • jquery-ui-rails 5.x//= require jquery-ui/sortable@md1961@github의 평론 참조)
  • jquery-ui-rails 6.x //= require jquery-ui/widgets/sortable ( Docs: Mention how the widget files moved in 6.0.0 )
  • 3. sort 동작 준비


    Ajax에서 데이터를 업데이트할 수 있도록sort 동작을 준비했습니다.
    routes.rb
     Rails.application.routes.draw do
    -  resources :fruits
    +  resources :fruits do
    +    put :sort
    +  end
    
       root to: 'fruits#index'
     end
    
    fruits_controller.rb
    +# this action will be called via ajax
    +def sort
    +  fruit = Fruit.find(params[:fruit_id])
    +  fruit.update(fruit_params)
    +  render nothing: true
    +end
    
     private
    
       # Never trust parameters from the scary internet, only allow the white list through.
       def fruit_params
    -    params.require(:fruit).permit(:name)
    +    params.require(:fruit).permit(:name, :row_order_position)
       end
    
    sort 동작에서 요청된 기록의row업데이트order.
    하지만 사실은 roworder가 아니라 roworder_position 속성을 업데이트하는 중입니다.(ranked-model gem의 사양)

    4. JavaScript로 Ajax 요청 보내기


    그런 다음 Ajax 요청을 JavaScript로 보냅니다.
    여기는 테이블입니다.sort.js.커피라는 새 파일을 만들었습니다.
    table_sort.js.coffee
    +$ ->
    +  $('.table-sortable').sortable
    +    axis: 'y'
    +    items: '.item'
    +
    +    update: (e, ui) ->
    +      item = ui.item
    +      item_data = item.data()
    +      params = { _method: 'put' }
    +      params[item_data.modelName] = { row_order_position: item.index() }
    +      $.ajax
    +        type: 'POST'
    +        url: item_data.updateUrl
    +        dataType: 'json'
    +        data: params
    
    View 측도 JS와 함께 데이터 속성 및 CSS 클래스를 추가합니다.
    fruits/index.html.slim
     h1 Listing fruits
    
    -table.table.table-bordered
    +table.table.table-bordered.table-sortable
       thead
         tr
           th Name
           th
           th
           th
       tbody
         - @fruits.each do |fruit|
    -      tr
    +      tr.item(data = { model_name: fruit.class.name.underscore, update_url: fruit_sort_path(fruit) })
             td = fruit.name
             td = link_to 'Show', fruit
             td = link_to 'Edit', edit_fruit_path(fruit)
    
    

    5. 동작 확인


    드래그 앤 드롭 작업을 수행할 수 있습니다.
    화면을 돌려보세요.
    문제가 없다면 화면을 다시 불러와도 드래그할 때의 순서를 유지해야 한다.
    정상적으로 실행할 수 없을 때 로그를 열어 오류가 발생했는지 확인하십시오.
    정상적으로 돌아가면 이런 느낌의 일지가 나올 거예요.
    development.log
    Started PUT "/fruits/4/sort" for 127.0.0.1 at 2014-07-31 06:33:27 +0900
    Processing by FruitsController#sort as JSON
      Parameters: {"fruit"=>{"row_order_position"=>"1"}, "fruit_id"=>"4"}
      Fruit Load (0.1ms)  SELECT  "fruits".* FROM "fruits"  WHERE "fruits"."id" = ? LIMIT 1  [["id", 4]]
       (0.1ms)  begin transaction
      Fruit Load (1.1ms)  SELECT  "fruits"."id", "fruits"."row_order" FROM "fruits"  WHERE ("fruits"."id" != 4)  ORDER BY "fruits"."row_order" ASC LIMIT 2 OFFSET 0
      Fruit Load (0.1ms)  SELECT  "fruits"."id", "fruits"."row_order" FROM "fruits"  WHERE ("fruits"."id" != 4) AND "fruits"."row_order" = 1376257  ORDER BY "fruits"."id" ASC LIMIT 1
      SQL (1.2ms)  UPDATE "fruits" SET "row_order" = ?, "updated_at" = ? WHERE "fruits"."id" = 4  [["row_order", 1376257], ["updated_at", "2014-07-30 21:33:27.996058"]]
       (0.7ms)  commit transaction
      Rendered text template (0.0ms)
    Completed 200 OK in 23ms (Views: 1.9ms | ActiveRecord: 3.4ms)
    

    6. 메이크업 뷰


    기능상 이래도 되지만 외관을 좀 높여주세요.
    여긴 내가 좋아하는 곳이야 원하는 방식대로 변경할 수도 있고 아무것도 안 할 수도 있어

    커서 유형 수정


    커서가 테이블 위에 있을 때 커서 유형을 변경하여 정렬할 수 있습니다.

    여기는 테이블입니다.sort.css.scss라는 파일을 추가했습니다.
    table_sort.css.scss
    +.table-sortable {
    +  tr.item {
    +    cursor: row-resize;
    +  }
    +}
    

    드래그 앤 드롭 시 강조 표시


    드래그 앤 드롭 시 전체 행이 노란색으로 강조표시됩니다.

    application.js
    +//= require jquery.ui.effect-highlight
    
    table_sort.js.coffee
             url: item_data.updateUrl
             dataType: 'json'
             data: params
    +    stop: (e, ui) ->
    +      ui.item.children('td').effect('highlight')
    
    

    드래그의 너비를 표로 조정합니다


    이렇게 하면 드래그하는 행의 폭이 줄어들기 때문에 테이블의 폭에 맞춰야 합니다.
    table_sort.js.coffee
             url: item_data.updateUrl
             dataType: 'json'
             data: params
    +    start: (e, ui) ->
    +      tableWidth = $(this).width()
    +      cells = ui.item.children('td')
    +      widthForEachCell = tableWidth / cells.length + 'px'
    +      cells.css('width', widthForEachCell)
         stop: (e, ui) ->
           ui.item.children('td').effect('highlight')
    

    7. 터보링크 특유의 질문 회피


    Rails4에 새 프로그램을 만들면 기본적으로 Turbolinks가 유효합니다.
    따라서 다른 화면(show 또는 edit)에 들어간 후 index 화면으로 돌아갈 때 드래그할 수 없습니다.(table sort.js 를 호출할 수 없음)
    이 문제를 피하기 위해 우리는 jquery-turbolinksgem를 도입했다.
    Gemfile
    +gem 'jquery-turbolinks'
    
    $ bundle install
    
    application.관건은 js에서 터보링크스를 마지막에 두는 거야.
    application.js
     //= require jquery
    +//= require jquery.turbolinks
     //= require jquery_ujs
     //= require jquery.ui.sortable
     //= require jquery.ui.effect-highlight
    -//= require turbolinks
     //= require bootstrap
     //= require_tree .
    +//= require turbolinks
    

    보충: 기록이 있는 경우


    만약 이미 기록이 있다면, 어떤 규칙에 따라row나는 order란을 업데이트하는 것이 비교적 좋다고 생각한다.
    다음은 id순서roworder 표시줄을 업데이트할 때 샘플 스크립트입니다.
    ActiveRecord::Base.record_timestamps = false
    Fruit.transaction do
      Fruit.order(id: :desc).each do |fruit|
        fruit.update_attribute :row_order_position, 0
      end
    end
    ActiveRecord::Base.record_timestamps = true
    

    총결산


    실현하기 전에 반드시 몇 걸음을 걸어야 하지만,gem와 jQuery를 조합하면 의외로 간단하게 실현될 수 있다.
    같은 UI를 만들어야 하는 경우에는 반드시 참조해 주십시오!

    2014.08.02 추기: 테스트 코드를 쓰는 방법이 공개되었습니다!


    Rspec을 사용하여 이 드래그 앤 드롭 기능을 테스트하는 방법에 대해 설명했습니다.
    이쪽에도 스크린 배우가 있어요.Rspec 설정 방법부터 자세히 설명합니다.
    가능하면 이것도 읽어주세요.
    초보자를 환영합니다!RSpec3을 사용하여 드래그 앤 드롭 기능을 테스트하는 방법(화면 할당 포함)

    좋은 웹페이지 즐겨찾기