0
votes

I'm implementing Dragon Drop to create accessible, draggable lists. I need to add a button to each list item to allow it to be deleted, but no matter how I delegate the click on my button I cannot seem to prevent Dragon Drops default behavior from firing.

As such I've decided to place my delete buttons within another div and position them relative to their corresponding list item. However, because they are out of the flow of the document, users leveraging keyboard navigation will not get to any of the delete buttons until after they've gone through the entire list.

Lets say that I have the following structure:

<ul>
  <li id="item-1">Item 1</li>
  <li id="item-2>Item 2</li>
</ul>

<div>
  <button id="delete-item-1"></button>
  <button id="delete-item-2"></button>
</div>

Is there some way to affect keyboard navigation such that users will tab through elements in the following order?

  1. #item-1
  2. #delete-item-1
  3. #item-2
  4. #delete-item-2

I've tried setting sequential tabindex attributes, but that doesn't work. I'm assuming that's due to them not living within the same element.

1

1 Answers

0
votes

It's usually extremely difficult to change tab order manually and do it right. For that reason it's strongly discouraged, and even for a case like this one, where it seems legitimate at first sight, I wouldn't advise you to do it.

IF you really want to do it, you may use absolute tabindex with values greater than 0, or catch tab and shift+tab presses in keydown events and move the focus yourself, but none of these two solutions are ideal. Both are difficult to set up, and difficult to maintain correct at all times as the content of the list changes, without mentioning occasional browser bugs when you change tabindex positive values dynamically or when mixing the use of keyboard and mouse together.

The best would really be to find a solution so that you can have a structure like the following, which implicitely has the correct tab order:

<ul>
<li><button>Item 1</button><button>Delete item 1</button></li>
<li><button>Item 2</button><button>Delete item 2</button></li>
<li><button>Item 3</button><button>Delete item 3</button></li>
</ul>

I'm pretty sure that there is a solution. Play with event bubbling, propagation, and default preventing.

As an alternative and depending on your exact situation, you may remove entirely all delete buttons from keyboard navigation and provide another way to delete an item, for example by pressing the delete key. This would be especially interesting if your component is an ARIA listbox, and if you already provide proper up/down or left/Right arrow key navigation between items. Otherwise it would be almost useless if you don't already do so.