I'm trying to set up an accessibility feature for this bootstrap accordion. I added in the tabindex=0 to each <a> tag and I'm trying to ensure that if the user hits tab it will open up that corresponding dropdown/accordion. But as of now my code opens every single accordion option when the user hit the tab button. Is there a way to do a forEach on keydown?
$('.accordion-toggle').keydown(function(e) {
if (e.keyCode == 13) {
$('.collapse').addClass('show');
} else {
$('.collapse').removeClass('show')
}
});
<a
class="text-left w-100 btn btn-link accordion-toggle"
tabindex="0"
data-toggle="collapse"
data-target="#collapseEight"
aria-expanded="true"
aria-controls="collapseEight">
item 1 <i class="arrow down"></i>
</a>
<div id="collapseSeven" class="collapse" aria-labelledby="headingSeven" data-parent="#accordion">
<p> Content for this section</p>
</div>
<a
class="text-left w-100 btn btn-link accordion-toggle"
tabindex="0"
data-toggle="collapse"
data-target="#collapseEight"
aria-expanded="true"
aria-controls="collapseEight">
item 2 <i class="arrow down"></i>
</a>
<div id="collapseSeven" class="collapse" aria-labelledby="headingSeven" data-parent="#accordion">
<p> Content for this section</p>
</div>
You need to use document.activeElement, which will only act on selected accordion then find the right accordion parent and select the collapse element within it.. and you need to run the keydown on document level and check if the focus item is the accordion item, below solution is mix of pure Javascript and jQuery:
$(document).keydown(function(){
let focused = document.activeElement;
const pattern = /(?:^|\s)accordion-toggle(?:\s|$)/
if (document.activeElement.className.match(pattern)) {
$('.collapse').removeClass('show');
let element = document.activeElement;
$(element).closest('.accordion-item').find('.collapse').addClass('show');
}
});
Not sure if this was what you were after, but... If the tab key is pressed, then:
data-target is expanded.$(document).keydown(function(e) {
//console.log(e.keyCode)
if (e.keyCode == 9) {
setTimeout(() => {
let $focused = $(':focus');
if ($focused.hasClass('accordion-toggle')) {
//close all open ones
$('.collapsed').removeClass('show');
$($focused.data('target')).addClass('show')
}
}, 50)
}
});
.collapsed {
display: none;
}
.collapsed.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="text-left w-100 btn btn-link accordion-toggle" tabindex="0" data-toggle="collapse" data-target="#collapseEight" aria-expanded="true" aria-controls="collapseEight">
item 1 <i class="arrow down"></i>
</a>
<div id='collapseEight' class='collapsed'>Text from collapseEight</div>
<a class="text-left w-100 btn btn-link accordion-toggle" tabindex="0" data-toggle="collapse" data-target="#collapseNine" aria-expanded="true" aria-controls="collapseNine">
item 2 <i class="arrow down"></i>
</a>
<div id='collapseNine' class='collapsed'>Text from collapseNine</div>