/
githubmirror
/
pocketbase
Обзор
Документация
Войти
/
githubmirror
/
pocketbase
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
ui/src/fields/select/settings.js
180 строк
7 KB
Gani Georgiev
don't recreate the maxSelect inputs on each change
08 июн 2026, 14:26
08 июн 2026, 14:26
aa7be1e
Код
Авторство
О чём код?
// { // originalCollection: undefined, // collection: undefined, // field // get fieldIndex: int/-1, // get originalField: undefined // } export function settings(props) { const uniqueId = "f_" + app.utils.randomString(); const isMultipleOptions = [ { label: "Single", value: false }, { label: "Multiple", value: true }, ]; const optionsDropdown = t.div( { popover: "manual", className: "dropdown field-select-choices-dropdown", }, t.div({ className: "field-help m-t-0", style: "font-size: 0.9em" }, "New-line separated choices:"), t.div( { className: "field" }, t.textarea({ className: "autoexpand", required: true, value: () => { const vals = app.utils.toArray(props.field.values, false); return vals.join("\n"); }, oninput: (e) => { const vals = e.target.value.trimStart().replaceAll("\n\n", "\n").split("\n"); props.field.values = vals; // clear previous errors app.utils.deleteByPath(app.store.errors, `fields.${props.fieldIndex}.values`); }, onchange: (e) => { // filter duplicates and empty values const unique = new Set(); const vals = e.target.value.split("\n"); for (let val of vals) { if (val == "") { continue; } unique.add(val); } props.field.values = Array.from(unique); }, onblur: (e) => { if (!e.relatedTarget || !optionsDropdown.contains(e.relatedTarget)) { optionsDropdown.hidePopover(); } }, }), ), ); const watchers = [ // cap maxSelect value watch(() => { if (props.field.values?.length && props.field.maxSelect > props.field.values.length) { props.field.maxSelect = props.field.values.length; } }), ]; return app.components.fieldSettings(props, { header: [ t.div( { className: "field header-select field-select-choices-input", onunmount: () => { watchers.forEach((w) => w?.unwatch()); }, }, t.input({ type: "text", placeholder: "Add choices*", className: "txt-left inline-error", value: () => props.field.values?.join(" • ") || "", name: () => `fields.${props.fieldIndex}.values`, onfocus: (e) => { optionsDropdown?.showPopover({ source: e.target }); optionsDropdown.querySelector("textarea")?.focus(); return false; }, }), optionsDropdown, ), t.div( { className: "field header-select single-multiple-select", }, app.components.select({ required: true, options: isMultipleOptions, value: () => { return props.field.maxSelect > 1; }, onchange: (opts) => { if (opts?.[0]?.value) { props.field.maxSelect = props.field.values.length || 2; } else { props.field.maxSelect = 1; } }, }), ), ], content: () => t.div( { className: "grid sm" }, t.div( { className: "col-sm-12", hidden: () => props.field.maxSelect << 0 < 2 }, t.div( { className: "field" }, t.label({ htmlFor: uniqueId + ".maxSelect" }, "Max select"), t.input({ type: "number", id: uniqueId + ".maxSelect", placeholder: "Default to single", step: 1, min: 2, max: () => props.field.values?.length || 2, name: () => `fields.${props.fieldIndex}.maxSelect`, value: () => props.field.maxSelect || "", onchange: (e) => { const maxSelect = parseInt(e.target.value, 10); if (maxSelect > 1) { props.field.maxSelect = maxSelect; } else { props.field.maxSelect = 1; } }, }), ), ), t.div( { className: "col-sm-12" }, t.div( { className: "field" }, t.label({ htmlFor: uniqueId + ".help" }, "Help text"), t.input({ type: "text", id: uniqueId + ".help", name: () => `fields.${props.fieldIndex}.help`, value: () => props.field.help || "", oninput: (e) => (props.field.help = e.target.value), }), ), ), ), footer: () => [ t.div( { className: "field" }, t.input({ className: "sm", type: "checkbox", id: uniqueId + ".required", name: () => `fields.${props.fieldIndex}.required`, checked: () => !!props.field.required, onchange: (e) => (props.field.required = e.target.checked), }), t.label( { htmlFor: uniqueId + ".required" }, t.span({ className: "txt" }, "Required"), t.small({ className: "txt-hint" }, () => props.field.maxSelect > 1 ? "(!=[])" : "(!='')"), t.i({ className: "ri-information-line link-hint", ariaDescription: app.attrs.tooltip(() => `Requires the field value to be nonempty ${props.field.maxSelect > 1 ? "array" : "string"}.` ), }), ), ), ], }); }