feat(vocabLesson): enhance input handling for gap-fill exercises
All checks were successful
Deploy to production / deploy (push) Successful in 2m45s
All checks were successful
Deploy to production / deploy (push) Successful in 2m45s
- Added functionality to manage Enter key events for gap-fill and single input fields, improving user experience during exercises. - Introduced methods `onGapInputEnter` and `onSingleInputEnter` to streamline answer checking and navigation between input fields. - Updated input elements with refs for better focus management, ensuring a smoother interaction flow for users.
This commit is contained in:
@@ -613,6 +613,8 @@
|
|||||||
v-model="exerciseAnswers[exercise.id][index]"
|
v-model="exerciseAnswers[exercise.id][index]"
|
||||||
:placeholder="$t('socialnetwork.vocab.courses.enterAnswer')"
|
:placeholder="$t('socialnetwork.vocab.courses.enterAnswer')"
|
||||||
class="gap-input"
|
class="gap-input"
|
||||||
|
:ref="getGapInputRef(exercise.id, index)"
|
||||||
|
@keydown.enter.prevent="onGapInputEnter(exercise, index)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button @click="checkAnswer(exercise.id)" :disabled="!hasAllGapsFilled(exercise)">
|
<button @click="checkAnswer(exercise.id)" :disabled="!hasAllGapsFilled(exercise)">
|
||||||
@@ -637,6 +639,8 @@
|
|||||||
v-model="exerciseAnswers[exercise.id]"
|
v-model="exerciseAnswers[exercise.id]"
|
||||||
:placeholder="$t('socialnetwork.vocab.courses.enterAnswer')"
|
:placeholder="$t('socialnetwork.vocab.courses.enterAnswer')"
|
||||||
class="transformation-input"
|
class="transformation-input"
|
||||||
|
:ref="'exercise-input-' + exercise.id"
|
||||||
|
@keydown.enter.prevent="onSingleInputEnter(exercise)"
|
||||||
/>
|
/>
|
||||||
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
||||||
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
||||||
@@ -662,6 +666,8 @@
|
|||||||
v-model="exerciseAnswers[exercise.id]"
|
v-model="exerciseAnswers[exercise.id]"
|
||||||
:placeholder="$t('socialnetwork.vocab.courses.buildSentencePlaceholder')"
|
:placeholder="$t('socialnetwork.vocab.courses.buildSentencePlaceholder')"
|
||||||
class="transformation-input"
|
class="transformation-input"
|
||||||
|
:ref="'exercise-input-' + exercise.id"
|
||||||
|
@keydown.enter.prevent="onSingleInputEnter(exercise)"
|
||||||
/>
|
/>
|
||||||
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
||||||
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
||||||
@@ -684,6 +690,8 @@
|
|||||||
v-model="exerciseAnswers[exercise.id]"
|
v-model="exerciseAnswers[exercise.id]"
|
||||||
:placeholder="$t('socialnetwork.vocab.courses.completeDialogPlaceholder')"
|
:placeholder="$t('socialnetwork.vocab.courses.completeDialogPlaceholder')"
|
||||||
class="transformation-input"
|
class="transformation-input"
|
||||||
|
:ref="'exercise-input-' + exercise.id"
|
||||||
|
@keydown.enter.prevent="onSingleInputEnter(exercise)"
|
||||||
/>
|
/>
|
||||||
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
<button @click="checkAnswer(exercise.id)" :disabled="!exerciseAnswers[exercise.id]">
|
||||||
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
{{ $t('socialnetwork.vocab.courses.checkAnswer') }}
|
||||||
@@ -2854,6 +2862,30 @@ export default {
|
|||||||
const matches = qData.text?.match(/\{gap\}/g);
|
const matches = qData.text?.match(/\{gap\}/g);
|
||||||
return matches ? matches.length : (qData.gaps || 1);
|
return matches ? matches.length : (qData.gaps || 1);
|
||||||
},
|
},
|
||||||
|
getGapInputRef(exerciseId, index) {
|
||||||
|
return `gap-input-${exerciseId}-${index}`;
|
||||||
|
},
|
||||||
|
onGapInputEnter(exercise, index) {
|
||||||
|
const gapCount = this.getGapCount(exercise);
|
||||||
|
// Bei mehreren Feldern: Enter springt weiter, beim letzten wird geprüft
|
||||||
|
if (gapCount > 1 && index < gapCount - 1) {
|
||||||
|
const nextRefKey = this.getGapInputRef(exercise.id, index + 1);
|
||||||
|
const nextRef = this.$refs[nextRefKey];
|
||||||
|
if (nextRef && nextRef.focus) {
|
||||||
|
nextRef.focus();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Letztes Feld (oder nur ein Feld): Antwort prüfen auslösen
|
||||||
|
this.checkAnswer(exercise.id);
|
||||||
|
},
|
||||||
|
onSingleInputEnter(exercise) {
|
||||||
|
const answer = this.exerciseAnswers[exercise.id];
|
||||||
|
if (!answer || (typeof answer === 'string' && !answer.trim())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.checkAnswer(exercise.id);
|
||||||
|
},
|
||||||
hasAllGapsFilled(exercise) {
|
hasAllGapsFilled(exercise) {
|
||||||
const answers = this.exerciseAnswers[exercise.id];
|
const answers = this.exerciseAnswers[exercise.id];
|
||||||
if (!answers || !Array.isArray(answers)) return false;
|
if (!answers || !Array.isArray(answers)) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user