diff --git a/public/js/components/Stv/Studentenverwaltung/List/New.js b/public/js/components/Stv/Studentenverwaltung/List/New.js index 1eab67967..e72d5fda9 100644 --- a/public/js/components/Stv/Studentenverwaltung/List/New.js +++ b/public/js/components/Stv/Studentenverwaltung/List/New.js @@ -2,6 +2,7 @@ import {CoreRESTClient} from '../../../../RESTClient.js'; import BsModal from '../../../Bootstrap/Modal.js'; import FhcFormValidation from '../../../Form/Validation.js'; import VueDatePicker from '../../../vueDatepicker.js.php'; +import accessibility from '../../../../directives/accessibility.js'; var _uuid = 0; @@ -11,6 +12,9 @@ export default { FhcFormValidation, VueDatePicker }, + directives: { + accessibility + }, props: { studiengangKz: Number }, diff --git a/public/js/directives/accessibility.js b/public/js/directives/accessibility.js new file mode 100644 index 000000000..b65d15309 --- /dev/null +++ b/public/js/directives/accessibility.js @@ -0,0 +1,83 @@ +export default { + created(el, binding) { + switch (binding.arg) { + case 'tab': + const [prev, next] = binding.modifiers.vertical ? ['ArrowUp', 'ArrowDown'] : ['ArrowRight', 'ArrowLeft']; + el.addEventListener('focus', () => { + el.setAttribute('aria-selected', true); + }); + el.addEventListener('blur', () => { + el.setAttribute('aria-selected', false); + }); + el.addEventListener('keydown', e => { + switch (e.code) { + case prev: + if (el.previousSibling?.setAttribute) { + el.previousSibling.setAttribute('tabindex', 0); + el.setAttribute('tabindex', -1); + el.previousSibling.focus(); + } + break; + case next: + if (el.nextSibling?.setAttribute) { + el.nextSibling.setAttribute('tabindex', 0); + el.setAttribute('tabindex', -1); + el.nextSibling.focus(); + } + break; + case 'Enter': + el.click(); + break; + } + }); + break; + } + }, + mounted(el, binding) { + switch (binding.arg) { + case 'tab': + //const [prev, next] = binding.modifiers.vertical ? ['up', 'down'] : ['right', 'left']; + let activetab = -1; + Array.from(el.parentNode.children).forEach((node, index) => { + node.setAttribute('aria-setsize', el.parentNode.children.length); + node.setAttribute('aria-posinset', index); + if (node.getAttribute('tabindex') == '0') + activetab = index; + }); + if (activetab == -1) { + el.setAttribute('tabindex', 0); + } else if (el.classList.contains('active')) { + el.parentNode.children[activetab].setAttribute('tabindex', -1); + el.setAttribute('tabindex', 0); + } else { + el.setAttribute('tabindex', -1); + } + break; + } + }, + beforeUnmount(el, binding) { + switch (binding.arg) { + case 'tab': + if (el.getAttribute('tabindex') == '0') { + if (el.previousSibling?.setAttribute) + el.previousSibling.setAttribute('tabindex', 0); + else if (el.nextSibling?.setAttribute) + el.nextSibling.setAttribute('tabindex', 0); + } + const pos = parseInt(el.getAttribute('aria-posinset')); + Array.from(el.parentNode.children).forEach((node, index) => { + node.setAttribute('aria-setsize', el.parentNode.children.length-1); + if (index > pos) + node.setAttribute('aria-posinset', index-1); + }); + break; + } + }, + unmounted(el, binding) { + switch (binding.arg) { + case 'tab': + console.log(el.parentNode); + break; + } + } +} \ No newline at end of file