Last active
November 8, 2022 22:23
-
-
Save DeathStapler/1a0e7374f4a760f05e58dc0ac80449a8 to your computer and use it in GitHub Desktop.
Making JetSmartFilters checkbox, radio, and visual filters more accessible
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
<script> | |
var radioGroupClass='.jet-radio-list'; | |
var radioClass='.jet-radio-list__button'; | |
var radioInputClass='.jet-radio-list__input'; | |
var visualGroupClass='.jet-color-image-list'; | |
var visualClass='.jet-color-image-list__button'; | |
var visualInputClass='.jet-color-image-list__input'; | |
var checkboxGroupClass='.jet-checkboxes-list'; | |
var checkboxClass='.jet-checkboxes-list__button'; | |
var checkboxInputClass='.jet-checkboxes-list__input'; | |
jQuery(document).ready(function($ ) { | |
filterRadioWidgetInit(); | |
filterCheckboxWidgetInit(); | |
filterVisualWidgetInit(); | |
$(document).on('jet-filter-content-rendered', function() { | |
setTimeout(function () { | |
filterRadioWidgetInit(); | |
filterCheckboxWidgetInit(); | |
filterVisualWidgetInit(); | |
}, 1); | |
}); | |
//////////////////////////////// | |
// RADIO BUTTON | |
function filterRadioWidgetInit() { | |
$(radioGroupClass).each(function () { | |
$(this).attr('role', 'radiogroup'); | |
$(this).find(radioClass).each(function () { | |
$(this).attr('role', 'radio'); | |
initAttr(this, 'aria-checked'); | |
}); | |
if ($(this).find(radioClass + '.aria-checked').length > 0) { | |
$(this).find(radioClass).each(function () { | |
initTabIndex(this, 'aria-checked'); | |
}); | |
} | |
else { | |
$(this).find(radioClass).each(function () { | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).find(radioClass).first().attr('tabindex', '0'); | |
} | |
}); | |
$(radioClass).off('keydown').on('keydown', function(e) { | |
switch (e.which) { | |
case 37: | |
case 38: | |
e.preventDefault(); | |
gotoPrevElement($(this), '.jet-filter-row', radioClass).focus(); | |
break; | |
case 39: | |
case 40: | |
e.preventDefault(); | |
gotoNextElement($(this), '.jet-filter-row', radioClass).focus(); | |
break; | |
case 13: | |
case 32: | |
e.preventDefault(); | |
var input=$(this).parent().find(radioInputClass); | |
// Reset aria-press for radios. They will be reset after filter update | |
$(this).closest(radioGroupClass).find(radioClass).each(function() { | |
$(this).removeClass('aria-checked'); | |
$(this).attr('aria-checked', 'false'); | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).attr('tabindex', '0'); | |
simulateClick(this, input, 'aria-checked', 'checked'); | |
break; | |
} | |
}); | |
$(radioClass).off('click').on('click', function() { | |
var input=$(this).parent().find(radioInputClass); | |
$(this).closest(radioGroupClass).find(radioClass).each(function() { | |
$(this).removeClass('aria-checked'); | |
$(this).attr('aria-checked', 'false'); | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).attr('tabindex', '0'); | |
setClassAndAriaFromInput(this, input, 'checked', 'aria-checked'); | |
}); | |
} | |
//////////////////////////////// | |
// CHECKBOX | |
function filterCheckboxWidgetInit() { | |
$(checkboxGroupClass).each(function () { | |
$(this).attr('role', 'group'); | |
}); | |
$(checkboxClass).each(function() { | |
$(this).attr('role', 'checkbox'); | |
$(this).attr('tabindex', '0'); | |
initAttr(this, 'aria-checked'); | |
}); | |
$(checkboxClass).off('keydown').on('keydown', function(e) { | |
switch (e.which) { | |
case 37: | |
case 38: | |
e.preventDefault(); | |
gotoPrevElement($(this), '.jet-filter-row', checkboxClass).focus(); | |
break; | |
case 39: | |
case 40: | |
e.preventDefault(); | |
gotoNextElement($(this), '.jet-filter-row', checkboxClass).focus(); | |
break; | |
case 13: | |
case 32: | |
e.preventDefault(); | |
var input=$(this).parent().find(checkboxInputClass); | |
simulateClick(this, input, 'aria-checked', 'checked'); | |
break; | |
} | |
}); | |
$(checkboxClass).off('click').on('click', function() { | |
var input=$(this).parent().find(checkboxInputClass); | |
setClassAndAriaFromInput(this, input, 'checked', 'aria-checked'); | |
}); | |
} | |
//////////////////////////////// | |
// VISUAL FILTER | |
function filterVisualWidgetInit() { | |
$(visualGroupClass).each(function () { | |
$(this).attr('role', 'radiogroup'); | |
$(this).find(visualClass).each(function () { | |
$(this).attr('role', 'radio'); | |
initAttr(this, 'aria-checked'); | |
}); | |
if ($(this).find(visualClass + '.aria-checked').length > 0) { | |
$(this).find(radioClass).each(function () { | |
initTabIndex(this, 'aria-checked'); | |
}); | |
} else { | |
$(this).find(visualClass).each(function () { | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).find(visualClass).first().attr('tabindex', '0'); | |
} | |
}); | |
$(visualClass).off('keydown').on('keydown', function(e) { | |
switch (e.which) { | |
case 37: | |
case 38: | |
e.preventDefault(); | |
gotoPrevElement($(this), '.jet-filter-row', visualClass).focus(); | |
break; | |
case 39: | |
case 40: | |
e.preventDefault(); | |
gotoNextElement($(this), '.jet-filter-row', visualClass).focus(); | |
break; | |
case 13: | |
case 32: | |
e.preventDefault(); | |
var input=$(this).parent().find(visualInputClass); | |
// Reset aria-press for radios. They will be reset after filter update | |
$(this).closest(visualGroupClass).find(visualClass).each(function() { | |
$(this).removeClass('aria-checked'); | |
$(this).attr('aria-checked', 'false'); | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).attr('tabindex', '0'); | |
simulateClick(this, input, 'aria-checked', 'checked'); | |
break; | |
} | |
}); | |
$(visualClass).off('click').on('click', function() { | |
var input=$(this).parent().find(visualInputClass); | |
$(this).closest(visualGroupClass).find(visualClass).each(function() { | |
$(this).removeClass('aria-checked'); | |
$(this).attr('aria-checked', 'false'); | |
$(this).attr('tabindex', '-1'); | |
}); | |
$(this).attr('tabindex', '0'); | |
setClassAndAriaFromInput(this, input, 'checked', 'aria-checked'); | |
}); | |
} | |
//////////////////// SUPPORT FUNCTIONS //////////////////////////// | |
function gotoNextElement(t, closestElem, findElem) { | |
var next=t.closest(closestElem).next()[0]; | |
if (next===undefined) { | |
next = t.closest(closestElem).prevAll().last()[0]; | |
} | |
if (next !==undefined) { | |
return $(next).find(findElem); | |
} | |
return undefined; | |
} | |
function gotoPrevElement(t, closestElem, findElem) { | |
var prev=t.closest(closestElem).prev()[0]; | |
if (prev===undefined) { | |
prev = t.closest(closestElem).nextAll().last()[0]; | |
} | |
if (prev !==undefined) { | |
return $(prev).find(findElem); | |
} | |
return undefined; | |
} | |
function initTabIndex(t, attr) { | |
if ($(t).hasClass(attr)) { | |
$(t).attr('tabindex', '0'); | |
} else { | |
$(t).attr('tabindex', '-1'); | |
} | |
} | |
function initAttr(t, attr) { | |
if ($(t).hasClass(attr)) { | |
$(t).attr(attr, 'true'); | |
} else { | |
$(t).attr(attr, 'false'); | |
} | |
} | |
function simulateClick(t, input, attr, prop) { | |
setClassAndAriaFromInput(t, input, prop, attr); | |
input.trigger('click'); | |
} | |
function setClassAndAriaFromInput(t, input, prop, attr) { | |
if (input.prop(prop)===true) { | |
$(t).removeClass(attr); | |
$(t).attr(attr, 'false'); | |
} else { | |
$(t).attr(attr, 'true'); | |
$(t).addClass(attr); | |
} | |
} | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Does not support Tri-state checkboxes.