Skip to content

Instantly share code, notes, and snippets.

@joshuabenuck
Created May 20, 2019 04:02
Show Gist options
  • Save joshuabenuck/6dd9277df071cf9edfe0b74f7c06db27 to your computer and use it in GitHub Desktop.
Save joshuabenuck/6dd9277df071cf9edfe0b74f7c06db27 to your computer and use it in GitHub Desktop.
Class based item drag and drop refactor
class DragOp
start: (_, ui) =>
@origCursor = $('body').css('cursor')
$item = ui.item
$placeholder = ui.placeholder
# Create a copy that we control since sortable removes theirs too early.
# Insert after the placeholder to prevent adding history when item not moved.
# Clear out the styling they add. Updates to jquery ui can affect this.
$item.clone().insertAfter($placeholder).hide().addClass("shadow-copy")
.css({width: '', height: '', position: '', zIndex: ''})
.removeAttr('data-id')
_equals: (a, b) => a and b and a.get(0) == b.get(0)
over: (_, ui) =>
# Called when our destination page changes
return
changeMouseCursor: (evt, ui) =>
# These should ideally be split across start and over, but jquery ui
# clears them out unexpectedly.
@$item = ui.item
@$sourcePage = @$item.data('pageElement')
@sourceIsGhost = @$sourcePage.hasClass('ghost')
$placeholder = ui.placeholder
@$destinationPage = $placeholder.parents('.page:first')
@destinationIsGhost = @$destinationPage.hasClass('ghost')
#console.log 'over', @$sourcePage, @$destinationPage
@moveWithinPage = @_equals(@$sourcePage, @$destinationPage)
@moveBetweenDuplicatePages = not @moveWithinPage and \
@$sourcePage.attr('id') == @$destinationPage.attr('id')
# Called on every mouse move during a drag
@copying = false
if @destinationIsGhost or @moveBetweenDuplicatePages
$('body').css('cursor', 'no-drop')
$('.shadow-copy').hide()
else if @sourceIsGhost or (evt.shiftKey and not @moveWithinPage)
@copying = true
$('body').css('cursor', 'copy')
$('.shadow-copy').show()
else
$('body').css('cursor', 'move')
$('.shadow-copy').hide()
return
stop: (evt, ui) =>
# Called at the end of a drag operation
if @destinationIsGhost or @moveBetweenDuplicatePages
$(evt.target).sortable('cancel')
return
@item = getItem(@$item)
if @moveWithinPage
console.log 'move within page'
order = @$destinationPage.find('.story').children()
.map((_, value) -> $(value).attr('data-id')).get()
pageHandler.put @$destinationPage, {id: @item.id, type: 'move', order: order}
return
if @copying
console.log 'copying'
# If making a copy, update the temp clone on the source page so it
# we don't lose the version there.
$('.shadow-copy').removeClass('shadow-copy')
.data(@$item.data()).attr({'data-id': @$item.attr('data-id')})
else
console.log 'moving'
# Record removal from source page.
console.log 'drag from', @$sourcePage.find('h1').text()
pageHandler.put @$sourcePage, {id: @item.id, type: 'remove'}
console.log 'journal update'
# Either way, record addition to destinatin page.
@$item.data 'pageElement', @$destinationPage
$before = @$item.prev('.item')
before = getItem($before)
@item = aliasItem @$destinationPage, @$item, @item
pageHandler.put @$destinationPage,
{id: @item.id, type: 'add', @item, after: before?.id}
return
cleanup: (evt, ui) =>
# Called at the end of a drag operation
console.log 'cleanup'
$('body').css('cursor', @origCursor)
$('.shadow-copy').remove()
return
initDragging = ($page) ->
options =
connectWith: '.page .story'
placeholder: 'item-placeholder'
forcePlaceholderSize: true
dragOp = new DragOp()
$story = $page.find('.story')
$story.sortable(options)
.on 'sortstart', dragOp.start
.on 'sortover', dragOp.over
.on 'sort', dragOp.changeMouseCursor
.on 'sortstop', dragOp.stop
.on 'sortstop', dragOp.cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment