68 lines
3.5 KiB
JavaScript
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;
|
|
}
|