added free text input with security measures

This commit is contained in:
2026-05-26 13:43:44 +02:00
parent 244fd16140
commit aefb1b6440
7 changed files with 143 additions and 3 deletions

View File

@ -20,6 +20,7 @@ const LAYOUT_TYPES = [
{ value: 'value_spinner', label: 'Value Spinner' },
{ value: 'date_spinner', label: 'Date Spinner' },
{ value: 'string_spinner', label: 'String Spinner' },
{ value: 'free_text', label: 'Free Text' },
{ value: 'client_coach_code_question', label: 'Client / Coach Code' },
{ value: 'client_not_signed', label: 'Client Not Signed' },
{ value: 'last_page', label: 'Last Page' },
@ -165,6 +166,28 @@ function configFormHTML(layout, config, prefix) {
<textarea id="${prefix}_stringOptions" rows="4" style="font-family:monospace;font-size:.85rem">${(config.options || []).join('\n')}</textarea>
</div>`;
break;
case 'free_text':
html = `
<div class="form-row">
<div class="form-group">
<label>Hint key (optional)</label>
<input type="text" id="${prefix}_hint" value="${esc(config.hint || '')}" placeholder="e.g. enter_text_to_continue">
</div>
<div class="form-group">
<label>Max length</label>
<input type="number" id="${prefix}_maxLength" value="${config.maxLength ?? 500}" min="1" max="10000">
</div>
</div>
<div class="form-group">
<label class="checkbox-label" style="display:inline-flex">
<input type="checkbox" id="${prefix}_multiline" ${config.multiline ? 'checked' : ''}> Multiline input
</label>
</div>
<div class="form-group">
<label>Extra text key (optional)</label>
<input type="text" id="${prefix}_textKey" value="${esc(config.textKey || '')}" placeholder="e.g. additional_notes_label">
</div>`;
break;
case 'client_coach_code_question':
html = `
<div class="form-row">
@ -249,6 +272,14 @@ function readConfigFromForm(layout, prefix) {
if (opts.length) config.options = opts;
break;
}
case 'free_text': {
if (val('textKey')) config.textKey = val('textKey');
if (val('hint')) config.hint = val('hint');
const ml = parseInt(val('maxLength') || '500', 10);
if (!Number.isNaN(ml) && ml > 0) config.maxLength = Math.min(ml, 10000);
if (document.getElementById(`${prefix}_multiline`)?.checked) config.multiline = true;
break;
}
case 'client_coach_code_question':
if (val('hint1')) config.hint1 = val('hint1');
if (val('hint2')) config.hint2 = val('hint2');

View File

@ -43,6 +43,17 @@
},
{
"id": "q3b",
"_comment": "Freitext-Eingabe (einzeilig oder mehrzeilig). maxLength und hint sind optional. Eingaben werden gegen SQL-Injection-Muster gefiltert.",
"layout": "free_text",
"question": "other_accommodation",
"hint": "enter_text_to_continue",
"maxLength": 500,
"multiline": true
},
{
"id": "q4",
"_comment": "Frage mit Spinner zur Auswahl des Datums",