Skip to content

Instantly share code, notes, and snippets.

@robby1066
Last active July 20, 2022 16:47
Show Gist options
  • Save robby1066/4ac279e415e682bc2ed6d266a049fc5d to your computer and use it in GitHub Desktop.
Save robby1066/4ac279e415e682bc2ed6d266a049fc5d to your computer and use it in GitHub Desktop.
Javascript for up and down keyboard-accessible controls on a sortable list with sortable.js
// 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()
}
}
}
@robby1066
Copy link
Author

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.

@elfeffe
Copy link

elfeffe commented Jul 10, 2021

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment