Last active
July 20, 2022 16:47
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you