mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-07 08:00:15 +02:00
feat: answer field UX improvements
- Auto-add one empty answer field when opening a blank question form - Auto-append new empty field when typing in the last answer field - Strip empty answer rows before submit (novalidate + JS cleanup) - Tab key skips correct/delete buttons, jumping straight to next answer
This commit is contained in:
@@ -8,6 +8,29 @@ export default class extends Controller {
|
|||||||
this.index = this.collectionTarget.children.length;
|
this.index = this.collectionTarget.children.length;
|
||||||
this._setupDrag();
|
this._setupDrag();
|
||||||
this._syncOrdering();
|
this._syncOrdering();
|
||||||
|
|
||||||
|
if (this.index === 0) {
|
||||||
|
this.addItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.collectionTarget.addEventListener('input', (e) => {
|
||||||
|
if (e.target.type !== 'text') return;
|
||||||
|
const item = e.target.closest('[data-collection-item]');
|
||||||
|
const last = [...this.collectionTarget.children].at(-1);
|
||||||
|
if (item && item === last && e.target.value.trim() !== '') {
|
||||||
|
this.addItem();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = this.element.closest('form');
|
||||||
|
if (form) {
|
||||||
|
form.addEventListener('submit', () => {
|
||||||
|
[...this.collectionTarget.children].forEach(item => {
|
||||||
|
const input = item.querySelector('input[type="text"]');
|
||||||
|
if (input && input.value.trim() === '') item.remove();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addItem() {
|
addItem() {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
<span class="text-muted" data-drag-handle style="cursor: grab" title="{{ 'Drag to reorder'|trans }}"><i class="bi bi-grip-vertical"></i></span>
|
<span class="text-muted" data-drag-handle style="cursor: grab" title="{{ 'Drag to reorder'|trans }}"><i class="bi bi-grip-vertical"></i></span>
|
||||||
<div class="flex-grow-1">{{ form_widget(answerForm.text) }}</div>
|
<div class="flex-grow-1">{{ form_widget(answerForm.text) }}</div>
|
||||||
<div class="d-none">{{ form_widget(answerForm.isRightAnswer) }}</div>
|
<div class="d-none">{{ form_widget(answerForm.isRightAnswer) }}</div>
|
||||||
<button type="button"
|
<button type="button" tabindex="-1"
|
||||||
class="btn btn-sm {{ answerForm.isRightAnswer.vars.checked ? 'btn-success' : 'btn-danger' }}"
|
class="btn btn-sm {{ answerForm.isRightAnswer.vars.checked ? 'btn-success' : 'btn-danger' }}"
|
||||||
title="{{ 'Toggle correct answer'|trans }}"
|
title="{{ 'Toggle correct answer'|trans }}"
|
||||||
onclick="var cb=this.closest('[data-collection-item]').querySelector('input[type=checkbox]');cb.checked=!cb.checked;this.classList.toggle('btn-success',cb.checked);this.classList.toggle('btn-danger',!cb.checked);this.querySelector('i').className=cb.checked?'bi bi-check-lg':'bi bi-x-lg'">
|
onclick="var cb=this.closest('[data-collection-item]').querySelector('input[type=checkbox]');cb.checked=!cb.checked;this.classList.toggle('btn-success',cb.checked);this.classList.toggle('btn-danger',!cb.checked);this.querySelector('i').className=cb.checked?'bi bi-check-lg':'bi bi-x-lg'">
|
||||||
<i class="{{ answerForm.isRightAnswer.vars.checked ? 'bi bi-check-lg' : 'bi bi-x-lg' }}"></i>
|
<i class="{{ answerForm.isRightAnswer.vars.checked ? 'bi bi-check-lg' : 'bi bi-x-lg' }}"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
<button type="button" tabindex="-1" class="btn btn-sm btn-outline-danger"
|
||||||
data-action="bo--form-collection#removeItem"><i class="bi bi-trash"></i></button>
|
data-action="bo--form-collection#removeItem"><i class="bi bi-trash"></i></button>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% import 'backoffice/partials/answer_row.html.twig' as macros %}
|
{% import 'backoffice/partials/answer_row.html.twig' as macros %}
|
||||||
|
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {attr: {novalidate: 'novalidate'}}) }}
|
||||||
{{ form_row(form.question) }}
|
{{ form_row(form.question) }}
|
||||||
{{ form_row(form.reusable) }}
|
{{ form_row(form.reusable) }}
|
||||||
{{ form_row(form.labels) }}
|
{{ form_row(form.labels) }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% import 'backoffice/partials/answer_row.html.twig' as macros %}
|
{% import 'backoffice/partials/answer_row.html.twig' as macros %}
|
||||||
|
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {attr: {novalidate: 'novalidate'}}) }}
|
||||||
{{ form_row(form.question) }}
|
{{ form_row(form.question) }}
|
||||||
|
|
||||||
<div data-controller="bo--form-collection"
|
<div data-controller="bo--form-collection"
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-danger" data-action="click->bo--quiz#clearQuiz">
|
<button class="btn btn-danger rounded-0" data-action="click->bo--quiz#clearQuiz">
|
||||||
{{ 'Clear Quiz...'|trans }}
|
{{ 'Clear Quiz...'|trans }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger rounded-0" data-action="click->bo--quiz#deleteQuiz">
|
<button class="btn btn-danger rounded-0" data-action="click->bo--quiz#deleteQuiz">
|
||||||
|
|||||||
Reference in New Issue
Block a user