Loading editor/html/js/survey-manager.js +126 −7 Changes for editor/html/js/survey-manager.js: 126 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -38,15 +38,23 @@ var SurveyManager = (function() { nodes.forEach(function(n) { var opts = []; n.querySelectorAll('Option').forEach(function(o) { opts.push({ value: o.getAttribute('value') || '', label: o.textContent || '' }); opts.push({ value: o.getAttribute('value') || '', label: o.textContent || '', icon: o.getAttribute('icon') || '' }); }); var maxsizeAttr = n.getAttribute('maxsize'); questions.push({ id: n.getAttribute('id') || '', parent_id: n.getAttribute('parent_id') || '', question_type: n.getAttribute('type') || 'text', label: n.getAttribute('label') || '', order_idx: parseInt(n.getAttribute('order_idx') || '0', 10), options: opts options: opts, accept_types: n.getAttribute('accept') || '', max_file_size_mb: maxsizeAttr ? Math.round(parseInt(maxsizeAttr, 10) / 104857.6) / 10 : 5, max_file_count: parseInt(n.getAttribute('maxcount') || '5', 10) }); }); return questions; Loading @@ -60,13 +68,19 @@ var SurveyManager = (function() { + ' type="' + escAttr(q.question_type) + '"' + ' label="' + escAttr(q.label) + '"' + ' order_idx="' + (q.order_idx || 0) + '"'; if (q.question_type === 'image') { if (q.accept_types) attrs += ' accept="' + escAttr(q.accept_types) + '"'; if (q.max_file_size_mb) attrs += ' maxsize="' + Math.round(q.max_file_size_mb * 1048576) + '"'; if (q.max_file_count) attrs += ' maxcount="' + q.max_file_count + '"'; } if (!q.options || q.options.length === 0) { lines.push(' <Question' + attrs + '/>'); } else { lines.push(' <Question' + attrs + '>'); q.options.forEach(function(o) { lines.push(' <Option value="' + escAttr(o.value) + '">' + escAttr(o.label) + '</Option>'); var oAttrs = ' value="' + escAttr(o.value) + '"'; if (o.icon) oAttrs += ' icon="' + escAttr(o.icon) + '"'; lines.push(' <Option' + oAttrs + '>' + escAttr(o.label) + '</Option>'); }); lines.push(' </Question>'); } Loading Loading @@ -335,7 +349,8 @@ var SurveyManager = (function() { selType.id = 'sm-q-type'; [['text','Text'],['textarea','Langtext'],['radio','Auswahl (Radio)'], ['checkbox','Mehrfachauswahl'],['select','Dropdown'], ['rating','Bewertung (1-5)'],['yesno','Ja / Nein']].forEach(function(t) { ['rating','Bewertung (1-5)'],['yesno','Ja / Nein'], ['image','Bild-Upload'],['icon','Bildauswahl (Icon)']].forEach(function(t) { var opt = document.createElement('option'); opt.value = t[0]; opt.textContent = t[1]; if (q.question_type === t[0]) opt.selected = true; Loading Loading @@ -378,8 +393,98 @@ var SurveyManager = (function() { optsWrap.appendChild(optsArea); panel.appendChild(optsWrap); // Icon options editor (for icon type) var iconOptsWrap = document.createElement('div'); iconOptsWrap.id = 'sm-q-icon-opts-wrap'; iconOptsWrap.style.display = q.question_type === 'icon' ? '' : 'none'; var iconOptsLbl = document.createElement('label'); iconOptsLbl.textContent = 'Antwortoptionen (Icon-Bilder)'; iconOptsLbl.style.cssText = 'display:block;font-weight:600;margin-bottom:4px;'; iconOptsWrap.appendChild(iconOptsLbl); var iconRowsDiv = document.createElement('div'); iconRowsDiv.id = 'sm-q-icon-rows'; iconRowsDiv.style.cssText = 'display:flex;flex-direction:column;gap:6px;'; function buildIconRow(opt) { var row = document.createElement('div'); row.className = 'sm-icon-opt-row'; row.style.cssText = 'display:grid;grid-template-columns:1fr 1fr 1fr auto auto;gap:4px;align-items:center;'; var inpVal = document.createElement('input'); inpVal.type = 'text'; inpVal.placeholder = 'wert'; inpVal.className = 'sm-icon-val'; inpVal.value = opt.value || ''; var inpLbl = document.createElement('input'); inpLbl.type = 'text'; inpLbl.placeholder = 'Text'; inpLbl.className = 'sm-icon-lbl'; inpLbl.value = opt.label || ''; var inpUrl = document.createElement('input'); inpUrl.type = 'text'; inpUrl.placeholder = 'Icon URL'; inpUrl.className = 'sm-icon-url'; inpUrl.value = opt.icon || ''; var btnBrowse = document.createElement('button'); btnBrowse.type = 'button'; btnBrowse.textContent = '🖼️'; btnBrowse.title = 'Bild aus Mediathek wählen'; btnBrowse.style.cssText = 'padding:4px 8px;cursor:pointer;'; (function(urlInp) { btnBrowse.addEventListener('click', function() { if (typeof MediaBrowser !== 'undefined') { MediaBrowser.open(function(mediaItem) { if (mediaItem && mediaItem.url) urlInp.value = mediaItem.url; }); } }); })(inpUrl); var btnRemove = document.createElement('button'); btnRemove.type = 'button'; btnRemove.textContent = '×'; btnRemove.style.cssText = 'padding:4px 8px;cursor:pointer;background:#c00;color:#fff;border:none;border-radius:3px;'; btnRemove.addEventListener('click', function() { row.remove(); }); row.appendChild(inpVal); row.appendChild(inpLbl); row.appendChild(inpUrl); row.appendChild(btnBrowse); row.appendChild(btnRemove); return row; } (q.options || []).forEach(function(opt) { iconRowsDiv.appendChild(buildIconRow(opt)); }); iconOptsWrap.appendChild(iconRowsDiv); var btnAddIcon = document.createElement('button'); btnAddIcon.type = 'button'; btnAddIcon.textContent = '+ Option'; btnAddIcon.style.cssText = 'margin-top:6px;padding:4px 12px;cursor:pointer;'; btnAddIcon.addEventListener('click', function() { iconRowsDiv.appendChild(buildIconRow({ value: '', label: '', icon: '' })); }); iconOptsWrap.appendChild(btnAddIcon); panel.appendChild(iconOptsWrap); // Image upload settings (for image type) var imgSettingsWrap = document.createElement('div'); imgSettingsWrap.id = 'sm-q-img-settings-wrap'; imgSettingsWrap.style.display = q.question_type === 'image' ? '' : 'none'; function addImgField(id, labelText, type, placeholder, value) { var wrap = document.createElement('div'); wrap.className = 'set-field'; var lbl = document.createElement('label'); lbl.textContent = labelText; var inp = document.createElement('input'); inp.id = id; inp.type = type; inp.placeholder = placeholder; inp.value = value; wrap.appendChild(lbl); wrap.appendChild(inp); imgSettingsWrap.appendChild(wrap); } addImgField('sm-q-img-accept', 'Dateitypen (Accept)', 'text', 'image/*', q.accept_types || 'image/*'); addImgField('sm-q-img-maxsize', 'Max. Größe (MB)', 'number', '5', q.max_file_size_mb != null ? q.max_file_size_mb : 5); addImgField('sm-q-img-maxcount', 'Max. Anzahl Dateien', 'number', '5', q.max_file_count != null ? q.max_file_count : 5); panel.appendChild(imgSettingsWrap); selType.addEventListener('change', function() { optsWrap.style.display = ['radio','checkbox','select'].indexOf(this.value) >= 0 ? '' : 'none'; var v = this.value; optsWrap.style.display = ['radio','checkbox','select'].indexOf(v) >= 0 ? '' : 'none'; iconOptsWrap.style.display = v === 'icon' ? '' : 'none'; imgSettingsWrap.style.display = v === 'image' ? '' : 'none'; }); // Buttons Loading Loading @@ -503,8 +608,8 @@ var SurveyManager = (function() { var parent = el('sm-q-parent').value; var options = []; var optsRaw = (el('sm-q-opts') || {}).value || ''; if (['radio','checkbox','select'].indexOf(type) >= 0) { var optsRaw = (el('sm-q-opts') || {}).value || ''; optsRaw.split('\n').forEach(function(line) { line = line.trim(); if (!line) return; Loading @@ -515,6 +620,14 @@ var SurveyManager = (function() { options.push({ value: line, label: line }); } }); } else if (type === 'icon') { var iconRows = document.querySelectorAll('#sm-q-icon-rows .sm-icon-opt-row'); iconRows.forEach(function(row) { var v = row.querySelector('.sm-icon-val').value.trim(); var l = row.querySelector('.sm-icon-lbl').value.trim(); var u = row.querySelector('.sm-icon-url').value.trim(); if (v || l) options.push({ value: v, label: l, icon: u }); }); } var q = _editingQ; Loading @@ -523,6 +636,12 @@ var SurveyManager = (function() { q.parent_id = parent; q.options = options; if (type === 'image') { q.accept_types = (el('sm-q-img-accept') || {}).value || 'image/*'; q.max_file_size_mb = parseFloat((el('sm-q-img-maxsize') || {}).value) || 5; q.max_file_count = parseInt((el('sm-q-img-maxcount') || {}).value, 10) || 5; } renderQuestionTree(); renderQuestionEditor(q); autoSaveXml(); Loading Loading
editor/html/js/survey-manager.js +126 −7 Changes for editor/html/js/survey-manager.js: 126 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -38,15 +38,23 @@ var SurveyManager = (function() { nodes.forEach(function(n) { var opts = []; n.querySelectorAll('Option').forEach(function(o) { opts.push({ value: o.getAttribute('value') || '', label: o.textContent || '' }); opts.push({ value: o.getAttribute('value') || '', label: o.textContent || '', icon: o.getAttribute('icon') || '' }); }); var maxsizeAttr = n.getAttribute('maxsize'); questions.push({ id: n.getAttribute('id') || '', parent_id: n.getAttribute('parent_id') || '', question_type: n.getAttribute('type') || 'text', label: n.getAttribute('label') || '', order_idx: parseInt(n.getAttribute('order_idx') || '0', 10), options: opts options: opts, accept_types: n.getAttribute('accept') || '', max_file_size_mb: maxsizeAttr ? Math.round(parseInt(maxsizeAttr, 10) / 104857.6) / 10 : 5, max_file_count: parseInt(n.getAttribute('maxcount') || '5', 10) }); }); return questions; Loading @@ -60,13 +68,19 @@ var SurveyManager = (function() { + ' type="' + escAttr(q.question_type) + '"' + ' label="' + escAttr(q.label) + '"' + ' order_idx="' + (q.order_idx || 0) + '"'; if (q.question_type === 'image') { if (q.accept_types) attrs += ' accept="' + escAttr(q.accept_types) + '"'; if (q.max_file_size_mb) attrs += ' maxsize="' + Math.round(q.max_file_size_mb * 1048576) + '"'; if (q.max_file_count) attrs += ' maxcount="' + q.max_file_count + '"'; } if (!q.options || q.options.length === 0) { lines.push(' <Question' + attrs + '/>'); } else { lines.push(' <Question' + attrs + '>'); q.options.forEach(function(o) { lines.push(' <Option value="' + escAttr(o.value) + '">' + escAttr(o.label) + '</Option>'); var oAttrs = ' value="' + escAttr(o.value) + '"'; if (o.icon) oAttrs += ' icon="' + escAttr(o.icon) + '"'; lines.push(' <Option' + oAttrs + '>' + escAttr(o.label) + '</Option>'); }); lines.push(' </Question>'); } Loading Loading @@ -335,7 +349,8 @@ var SurveyManager = (function() { selType.id = 'sm-q-type'; [['text','Text'],['textarea','Langtext'],['radio','Auswahl (Radio)'], ['checkbox','Mehrfachauswahl'],['select','Dropdown'], ['rating','Bewertung (1-5)'],['yesno','Ja / Nein']].forEach(function(t) { ['rating','Bewertung (1-5)'],['yesno','Ja / Nein'], ['image','Bild-Upload'],['icon','Bildauswahl (Icon)']].forEach(function(t) { var opt = document.createElement('option'); opt.value = t[0]; opt.textContent = t[1]; if (q.question_type === t[0]) opt.selected = true; Loading Loading @@ -378,8 +393,98 @@ var SurveyManager = (function() { optsWrap.appendChild(optsArea); panel.appendChild(optsWrap); // Icon options editor (for icon type) var iconOptsWrap = document.createElement('div'); iconOptsWrap.id = 'sm-q-icon-opts-wrap'; iconOptsWrap.style.display = q.question_type === 'icon' ? '' : 'none'; var iconOptsLbl = document.createElement('label'); iconOptsLbl.textContent = 'Antwortoptionen (Icon-Bilder)'; iconOptsLbl.style.cssText = 'display:block;font-weight:600;margin-bottom:4px;'; iconOptsWrap.appendChild(iconOptsLbl); var iconRowsDiv = document.createElement('div'); iconRowsDiv.id = 'sm-q-icon-rows'; iconRowsDiv.style.cssText = 'display:flex;flex-direction:column;gap:6px;'; function buildIconRow(opt) { var row = document.createElement('div'); row.className = 'sm-icon-opt-row'; row.style.cssText = 'display:grid;grid-template-columns:1fr 1fr 1fr auto auto;gap:4px;align-items:center;'; var inpVal = document.createElement('input'); inpVal.type = 'text'; inpVal.placeholder = 'wert'; inpVal.className = 'sm-icon-val'; inpVal.value = opt.value || ''; var inpLbl = document.createElement('input'); inpLbl.type = 'text'; inpLbl.placeholder = 'Text'; inpLbl.className = 'sm-icon-lbl'; inpLbl.value = opt.label || ''; var inpUrl = document.createElement('input'); inpUrl.type = 'text'; inpUrl.placeholder = 'Icon URL'; inpUrl.className = 'sm-icon-url'; inpUrl.value = opt.icon || ''; var btnBrowse = document.createElement('button'); btnBrowse.type = 'button'; btnBrowse.textContent = '🖼️'; btnBrowse.title = 'Bild aus Mediathek wählen'; btnBrowse.style.cssText = 'padding:4px 8px;cursor:pointer;'; (function(urlInp) { btnBrowse.addEventListener('click', function() { if (typeof MediaBrowser !== 'undefined') { MediaBrowser.open(function(mediaItem) { if (mediaItem && mediaItem.url) urlInp.value = mediaItem.url; }); } }); })(inpUrl); var btnRemove = document.createElement('button'); btnRemove.type = 'button'; btnRemove.textContent = '×'; btnRemove.style.cssText = 'padding:4px 8px;cursor:pointer;background:#c00;color:#fff;border:none;border-radius:3px;'; btnRemove.addEventListener('click', function() { row.remove(); }); row.appendChild(inpVal); row.appendChild(inpLbl); row.appendChild(inpUrl); row.appendChild(btnBrowse); row.appendChild(btnRemove); return row; } (q.options || []).forEach(function(opt) { iconRowsDiv.appendChild(buildIconRow(opt)); }); iconOptsWrap.appendChild(iconRowsDiv); var btnAddIcon = document.createElement('button'); btnAddIcon.type = 'button'; btnAddIcon.textContent = '+ Option'; btnAddIcon.style.cssText = 'margin-top:6px;padding:4px 12px;cursor:pointer;'; btnAddIcon.addEventListener('click', function() { iconRowsDiv.appendChild(buildIconRow({ value: '', label: '', icon: '' })); }); iconOptsWrap.appendChild(btnAddIcon); panel.appendChild(iconOptsWrap); // Image upload settings (for image type) var imgSettingsWrap = document.createElement('div'); imgSettingsWrap.id = 'sm-q-img-settings-wrap'; imgSettingsWrap.style.display = q.question_type === 'image' ? '' : 'none'; function addImgField(id, labelText, type, placeholder, value) { var wrap = document.createElement('div'); wrap.className = 'set-field'; var lbl = document.createElement('label'); lbl.textContent = labelText; var inp = document.createElement('input'); inp.id = id; inp.type = type; inp.placeholder = placeholder; inp.value = value; wrap.appendChild(lbl); wrap.appendChild(inp); imgSettingsWrap.appendChild(wrap); } addImgField('sm-q-img-accept', 'Dateitypen (Accept)', 'text', 'image/*', q.accept_types || 'image/*'); addImgField('sm-q-img-maxsize', 'Max. Größe (MB)', 'number', '5', q.max_file_size_mb != null ? q.max_file_size_mb : 5); addImgField('sm-q-img-maxcount', 'Max. Anzahl Dateien', 'number', '5', q.max_file_count != null ? q.max_file_count : 5); panel.appendChild(imgSettingsWrap); selType.addEventListener('change', function() { optsWrap.style.display = ['radio','checkbox','select'].indexOf(this.value) >= 0 ? '' : 'none'; var v = this.value; optsWrap.style.display = ['radio','checkbox','select'].indexOf(v) >= 0 ? '' : 'none'; iconOptsWrap.style.display = v === 'icon' ? '' : 'none'; imgSettingsWrap.style.display = v === 'image' ? '' : 'none'; }); // Buttons Loading Loading @@ -503,8 +608,8 @@ var SurveyManager = (function() { var parent = el('sm-q-parent').value; var options = []; var optsRaw = (el('sm-q-opts') || {}).value || ''; if (['radio','checkbox','select'].indexOf(type) >= 0) { var optsRaw = (el('sm-q-opts') || {}).value || ''; optsRaw.split('\n').forEach(function(line) { line = line.trim(); if (!line) return; Loading @@ -515,6 +620,14 @@ var SurveyManager = (function() { options.push({ value: line, label: line }); } }); } else if (type === 'icon') { var iconRows = document.querySelectorAll('#sm-q-icon-rows .sm-icon-opt-row'); iconRows.forEach(function(row) { var v = row.querySelector('.sm-icon-val').value.trim(); var l = row.querySelector('.sm-icon-lbl').value.trim(); var u = row.querySelector('.sm-icon-url').value.trim(); if (v || l) options.push({ value: v, label: l, icon: u }); }); } var q = _editingQ; Loading @@ -523,6 +636,12 @@ var SurveyManager = (function() { q.parent_id = parent; q.options = options; if (type === 'image') { q.accept_types = (el('sm-q-img-accept') || {}).value || 'image/*'; q.max_file_size_mb = parseFloat((el('sm-q-img-maxsize') || {}).value) || 5; q.max_file_count = parseInt((el('sm-q-img-maxcount') || {}).value, 10) || 5; } renderQuestionTree(); renderQuestionEditor(q); autoSaveXml(); Loading