Skip to content

Instantly share code, notes, and snippets.

@peterclark
Last active August 21, 2023 12:21
Show Gist options
  • Save peterclark/701dc0904b8f2138a502e39a349d014d to your computer and use it in GitHub Desktop.
Save peterclark/701dc0904b8f2138a502e39a349d014d to your computer and use it in GitHub Desktop.
Rails drag and drop using HTML5 and acts_as_list
%table.table
%thead.table-active
%tr
%th Position
%th Name
%tbody
- @fruits.each do |fruit|
%tr.draggable{ draggable: true, id: "fruit-#{fruit.id}", data: { position: fruit.position, url: reorder_fruit_path(fruit, format: :js) }}
%td= fruit.position
%td= fruit.name
:css
[draggable] {
cursor: ns-resize;
}
.dragging {
background-color: #fe7d5d;
opacity: 0.5;
}
.enter {
background-color: #eee;
}
@keyframes highlight {
0% { background: white; }
50% { background: #fe7d5d; }
100% { background: white; }
}
.highlight {
animation: highlight 1s;
}
:coffeescript
$(document).on 'dragstart', 'tr.draggable', (e) ->
row = $(e.target).closest('tr')
row.addClass('dragging')
e.originalEvent.dataTransfer.setData('text', row.data('url'))
$(document).on 'drop', 'tr.draggable', (e) ->
e.preventDefault()
row = $(e.target).closest('tr')
row.removeClass('dragging enter')
moveToPosition = row.data('position')
url = e.originalEvent.dataTransfer.getData('text')
return if url == row.data('url')
$.post(url, { _method: 'PUT', fruit: { move_to_position: moveToPosition }})
$(document).on 'dragend', 'tr.draggable', (e) ->
row = $(e.target).closest('tr')
row.removeClass('dragging enter')
$(document).on 'dragenter dragleave', 'tr.draggable', (e) ->
row = $(e.target).closest('tr')
row.toggleClass('enter')
$(document).on 'dragover', 'tr.draggable', (e) ->
e.originalEvent.preventDefault()
e.originalEvent.dataTransfer.dropEffect = 'move'
class Fruit < ApplicationRecord
acts_as_list
scope :ordered, -> { order(position: :asc) }
end
class FruitsController < ApplicationController
def index
@fruits = Fruit.ordered
end
def reorder
position = params[:fruit][:move_to_position].to_i
@fruit = Fruit.find params[:id]
@fruit.insert_at(position) if position > 0
@fruits = Fruit.ordered
end
end
%h1 Fruits
.fruits-table
= render 'table'
$('.fruits-table').html "<%=j render 'table' %>"
$("#fruit-<%= @fruit.id %>").addClass 'highlight'
# ...
resources :fruits do
member do
put :reorder
end
end
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment