Fix Tab-Navigation on Chromium

Signed-off-by: Jonas Rittershofer <jotoeri@users.noreply.github.com>
This commit is contained in:
Jonas Rittershofer 2020-06-24 21:52:24 +02:00
parent 31cd45d582
commit 7057722772
3 changed files with 57 additions and 32 deletions

View file

@ -25,9 +25,7 @@
:class="{ 'question--edit': edit }" :class="{ 'question--edit': edit }"
:aria-label="t('forms', 'Question number {index}', {index})" :aria-label="t('forms', 'Question number {index}', {index})"
class="question" class="question"
@click="enableEdit" @click="enableEdit">
@focusin="onFocusIn"
@focusout="onFocusOut">
<!-- Drag handle --> <!-- Drag handle -->
<!-- TODO: implement arrow key mapping to reorder question --> <!-- TODO: implement arrow key mapping to reorder question -->
<div v-if="!readOnly" <div v-if="!readOnly"
@ -47,7 +45,8 @@
minlength="1" minlength="1"
:maxlength="maxQuestionLength" :maxlength="maxQuestionLength"
required required
@input="onTitleChange"> @input="onTitleChange"
@keydown.shift.tab.capture="nextDisableEdit">
<h3 v-else <h3 v-else
class="question__header-title" class="question__header-title"
:tabindex="computedTitleTabIndex" :tabindex="computedTitleTabIndex"
@ -180,34 +179,22 @@ export default {
* Allow edit-navigation through Tab-Key * Allow edit-navigation through Tab-Key
*/ */
onTitleFocus() { onTitleFocus() {
console.debug('On Title focus', this.$refs)
if (!this.readOnly) { if (!this.readOnly) {
this.enableEdit() this.enableEdit()
console.debug('Store NextTick')
this.$nextTick(() => { this.$nextTick(() => {
console.debug('NextTick!')
this.$refs.titleInput.focus() this.$refs.titleInput.focus()
}) })
} }
}, },
/**
* Enable & disable resp. edit, if focus jumps to next question (e.g. by tab-navigation)
* @param {Object} event The triggered focusIn/focusOut event
*/
onFocusIn(event) {
if (event.target.closest('.question') !== event.relatedTarget?.closest('.question')) {
this.enableEdit()
}
},
onFocusOut(event) {
if (event.target.closest('.question') !== event.relatedTarget?.closest('.question')) {
this.disableEdit()
}
},
/** /**
* Enable the edit mode * Enable the edit mode
*/ */
enableEdit() { enableEdit() {
console.debug('enableEdit')
if (!this.readOnly) { if (!this.readOnly) {
this.$emit('update:edit', true) this.$emit('update:edit', true)
} }
@ -217,11 +204,24 @@ export default {
* Disable the edit mode * Disable the edit mode
*/ */
disableEdit() { disableEdit() {
console.debug('disableEdit')
if (!this.readOnly) { if (!this.readOnly) {
this.$emit('update:edit', false) this.$emit('update:edit', false)
} }
}, },
nextDisableEdit(event) {
console.debug('nextDisable')
console.debug(event)
// event.preventDefault()
// this.disableEdit()
this.$nextTick(() => {
console.debug('Later!')
})
console.debug('trigger')
// this.disableEdit()
},
/** /**
* Delete this question * Delete this question
*/ */

View file

@ -39,8 +39,7 @@
<template v-for="(answer, index) in options"> <template v-for="(answer, index) in options">
<li v-if="!edit" <li v-if="!edit"
:key="answer.id" :key="answer.id"
class="question__item" class="question__item">
:class="{'question__item--last': (index === options.length-1),}">
<!-- Answer radio/checkbox + label --> <!-- Answer radio/checkbox + label -->
<!-- TODO: migrate to radio/checkbox component once available --> <!-- TODO: migrate to radio/checkbox component once available -->
<input :id="`${id}-answer-${answer.id}`" <input :id="`${id}-answer-${answer.id}`"
@ -55,7 +54,8 @@
:required="isRequired(answer.id)" :required="isRequired(answer.id)"
:type="isUnique ? 'radio' : 'checkbox'" :type="isUnique ? 'radio' : 'checkbox'"
@change="onChange($event, answer.id)" @change="onChange($event, answer.id)"
@keydown.enter.exact.prevent="onKeydownEnter"> @keydown.enter.exact.prevent="onKeydownEnter"
@focus="onFocusRadioInput">
<label v-if="!edit" <label v-if="!edit"
ref="label" ref="label"
:for="`${id}-answer-${answer.id}`" :for="`${id}-answer-${answer.id}`"
@ -153,15 +153,6 @@ export default {
// update parent // update parent
this.updateOptions(options) this.updateOptions(options)
} else {
// If edit becomes true by tabbing to last element, focus newAnswer-input
if (document.activeElement?.parentNode?.classList.contains('question__item--last')) {
this.$nextTick(() => {
if (this.$refs.inputNewAnswer) {
this.$refs.inputNewAnswer.focus()
}
})
}
} }
}, },
}, },
@ -188,6 +179,20 @@ export default {
this.$emit('update:values', [...new Set(values)]) this.$emit('update:values', [...new Set(values)])
}, },
/**
* If the focus gets onto one of the radio/checkbox inputs and readOnly is false, activate Edit and focus inputNewAnswer
* Necessary for Tab-Navigation on editing forms.
*/
onFocusRadioInput() {
console.debug('Inputfocus!')
if (!this.readOnly) {
this.enableEdit()
this.$nextTick(() => {
this.$refs.inputNewAnswer.focus()
})
}
},
/** /**
* Is the provided answer checked ? * Is the provided answer checked ?
* @param {number} id the answer id * @param {number} id the answer id

View file

@ -181,5 +181,25 @@ export default {
console.error(error) console.error(error)
} }
}, },
/**
* Enable the edit mode
*/
enableEdit() {
console.debug('enableEdit')
if (!this.readOnly) {
this.edit = true
}
},
/**
* Disable the edit mode
*/
disableEdit() {
console.debug('disableEdit')
if (!this.readOnly) {
this.edit = false
}
},
}, },
} }