Fix Tab-Navigation on Chromium
Signed-off-by: Jonas Rittershofer <jotoeri@users.noreply.github.com>
This commit is contained in:
parent
31cd45d582
commit
7057722772
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue