-
-
Save robby1066/4ac279e415e682bc2ed6d266a049fc5d to your computer and use it in GitHub Desktop.
// Move the element either up or down in the list | |
// this piggybacks on Sortablejs's `sort` function | |
// This code needs to have access to the Sortablejs object that controls the list. | |
// A couple of things you'll need to customize | |
// LIST_CONTAINER is the DOM element that shoud contain the list | |
// LIST_ITEM_SELECTOR is the | |
// (e.g. The UL where the LI elements should be sortable) | |
// You will probably want to customize these, or use a different way to select your list and list items | |
const listContainerSelector = 'UL#my-sortable-list' | |
const listItemSelector = 'LI.sortable-list-item' | |
// If your code already has access to the sortablejs object, | |
// comment this part out and update any references to `sortable_list` below | |
// to reference your sortablejs object | |
var sortable_list = Sortable.create(document.querySelector(listContainerSelector), { | |
dataIdAttr: 'data-sortable-id', // required to calculate the custom sort | |
// Any other sortablejs configuration... | |
handle: '.drag-handle', | |
animation: 250 | |
}) | |
moveElement(element, direction) { | |
// bail out if we get input that we don't expect | |
if (["up", "down"].includes(direction) == false ) { | |
return false | |
} | |
if (typeof(element.dataset.sortableId) == 'undefined') { | |
return false | |
} | |
// `sortableId` is whatever you've set in your sortablejs config for `dataIdAttr` | |
let sortableId = element.dataset.sortableId | |
let order = sortable_list.toArray() | |
let index = order.indexOf(sortableId) | |
// pull the item we're moving out of the order | |
order.splice(index, 1) | |
// put it back in at the correct position | |
if (direction == 'down') { | |
order.splice(index+1, 0, sortableId) | |
} else if (direction == 'up') { | |
order.splice(index-1, 0, sortableId) | |
} | |
sortable_list.sort(order, true) | |
} | |
// Attached to the up control's `onKeyDown` event | |
moveElementUp(event) { | |
// only proceed if `ENTER` was pressed - keyCode 13 | |
if (event.keyCode == 13) { | |
event.stopPropagation() | |
event.preventDefault() | |
// get the list item that contains the control that was activated | |
// (in this case, it matches the selector `DIV.topic-list-item`) | |
this.moveElement(event.currentTarget.closest(listItemSelector), 'up') | |
// Check the visibility of the control. | |
// If it's new place in the list caused 'up' or 'down' to be hidden, switch to the other one | |
if (window.getComputedStyle(event.currentTarget).display == 'none') { | |
event.currentTarget.parentNode.querySelector('A[data-direction=down]').focus() | |
} else { | |
event.currentTarget.focus() | |
} | |
} | |
} | |
// Attached to the down control's `onKeyDown` event | |
moveElementDown(event) { | |
if (event.keyCode == 13) { | |
event.stopPropagation() | |
event.preventDefault() | |
this.moveElement(event.currentTarget.closest(listItemSelector), 'down') | |
if (window.getComputedStyle(event.currentTarget).display == 'none') { | |
event.currentTarget.parentNode.querySelector('A[data-direction=up]').focus() | |
} else { | |
event.currentTarget.focus() | |
} | |
} | |
} |
This lives outside sortable, in a place that has access to the sortablejs object.
Upon re-reading it, I see a bug that will keep this code from just working in a general setting. (sorry, I pulled it from a Stimulusjs controller I was using it in)
this.sortable.sort(order, true)
in line 28 needs to refer to the sortable object you defined for the list with Sortable.create(...
I'll refactor and update.
Aside from that, this code should be generally usable anywhere you have access to the sortable object.
Updated to something that should work more generically now. There's a section at the top to define the sortablejs list and set selectors for the list and the list items. Should be usable as-is, but depending on your existing code you may want to modify it to point to your existing sortablejs obj.
Thank you
@robby1066 Where do you put this code?
Do you modify Sortable's code or you add it as a plugin?