Files
2026-10-29 11:57:29 +01:00

68 lines
3.5 KiB
JavaScript

// Generated, do not edit. sha256:374bda270315c76a934d2540ed9d4724c841659867d96ba0c265c5a8c61bbca3
import { esc } from './escape.js';
import { cellClassAttr } from './table-markup.js';
export function editInputHtml(col, vals, { options = [], convert = null } = {}) {
const e = col.edit;
const cur = vals[col.key];
if (e.render) return e.render(vals);
const react = e.reactive ? ' data-reactive="1"' : '';
const extra = e.attrs ? ' ' + Object.entries(e.attrs).map(([k, v]) => `${k}="${esc(v)}"`).join(' ') : '';
const phVal = typeof e.placeholder === 'function' ? e.placeholder(vals) : e.placeholder;
const ph = phVal ? ` placeholder="${esc(phVal)}"` : '';
if (e.type === 'select') {
const opts = options.map(o =>
`<option value="${esc(o.value)}"${String(o.value) === String(cur) ? ' selected' : ''}>${esc(o.label)}</option>`).join('');
return `<select class="input" data-field="${col.key}"${react}${extra}>${opts}</select>`;
}
if (e.type === 'checkbox') {
return `<label class="toggle-switch"><input type="checkbox" data-field="${col.key}"${react}${extra}${cur ? ' checked' : ''}><span class="toggle-track"></span></label>`;
}
const val = cur == null ? '' : esc(cur);
if (e.type === 'textarea') {
return `<textarea class="input tbl-textarea" data-field="${col.key}"${react}${extra}${ph} rows="2">${val}</textarea>`;
}
const type = e.type === 'number' ? 'number' : (e.type === 'date' ? 'date' : (e.type === 'time' ? 'time' : 'text'));
const inputHtml = `<input class="input" type="${type}" data-field="${col.key}"${react}${extra}${ph} value="${val}">`;
if (!e.convert || !convert || !convert.canConvert(e.convert(vals))) return inputHtml;
const cvLabel = esc(convert.label || '');
return `<div class="conv-field">${inputHtml}<button type="button" class="conv-trigger" data-convert="${col.key}" title="${cvLabel}" aria-label="${cvLabel}">${convert.icon || ''}</button></div>`;
}
export function editCellHtml(col, vals, opts) {
const vis = !col.edit.visible || col.edit.visible(vals);
if (col.edit.expand) return `<td${cellClassAttr(col)}></td>`;
if (!vis) return `<td${cellClassAttr(col)}></td>`;
return `<td${cellClassAttr(col)} data-label="${esc(col.label || '')}">${editInputHtml(col, vals, opts)}</td>`;
}
export function expandRowHtml({ editableCols, vals, error, colCount, optsFor, actions = '' }) {
const fields = editableCols
.filter(c => c.edit.expand && (!c.edit.visible || c.edit.visible(vals)))
.map(c => {
const full = c.edit.type === 'textarea' || c.edit.full;
return `<div class="form-group edit-expand-field${full ? ' is-full' : ''}">
<label class="form-label">${esc(c.label)}</label>${editInputHtml(c, vals, optsFor(c))}
</div>`;
}).join('');
const err = error ? `<div class="form-error edit-expand-error">${esc(error)}</div>` : '';
if (!fields && !err && !actions) return '';
const fieldsHtml = fields ? `<div class="flex gap-md edit-expand-fields">${fields}</div>` : '';
return `<tr class="edit-expand-row"><td colspan="${colCount}">
${fieldsHtml}${err}${actions}
</td></tr>`;
}
export function captureValues(scope, editableCols, vals) {
for (const c of editableCols) {
if (c.edit.read) {
vals[c.key] = c.edit.read(scope.querySelector(`[data-field="${c.key}"]`));
continue;
}
const node = scope.querySelector(`[data-field="${c.key}"]`);
if (!node) continue;
vals[c.key] = node.type === 'checkbox' ? node.checked : node.value;
}
return vals;
}