function multiAutoSelect() {
let config;
if (arguments.length === 1) {
config = arguments[0];
} else {
config = arguments[1];
config.options = arguments[0];
}
const {
value,
title,
description,
disabled,
autocomplete = "off",
placeholder,
size,
options,
label = "",
list = DOM.uid("autoSelect").id,
attr = (d) => d,
postRender = (d) => d
} = Array.isArray(config) ? { options: config } : config;
const optionsMap = new Map(options.map((o) => ["" + attr(o), o]));
const onAction = (fm) => {
const addToSelected = (d) => {
if (
optionsMap.has(fm.input.value) &&
fm.value.map((d) => "" + d).indexOf(fm.input.value) === -1
) {
fm.value.push(optionsMap.get(fm.input.value));
renderSelection();
fm.input.value = "";
fm.dispatchEvent(new Event("input", { bubbles: true }));
}
};
const renderSelected = (d) => {
const button = html`<button type="button" style="margin:0px; padding:0px;">✖️</button>`;
const ele = html`<span style="display: inline-block; margin: 7px 2px; border: solid 1px #ccc; border-radius: 5px;padding: 3px 6px; cursor:move; box-shadow: 1px 1px 1px #777; background: white">${attr(
d
)} ${button}</span>`;
button.addEventListener("click", (e) => {
fm.value.splice(fm.value.indexOf(d), 1);
ele.remove();
fm.dispatchEvent(new Event("input", { bubbles: true }));
fm.input.focus();
});
ele.addEventListener("dragover", (e) => {
ele.style["border-color"] = "orange";
});
ele.addEventListener("dragleave", (e) => {
ele.style["border-color"] = "#ccc";
});
ele.addEventListener("dragend", (e) => {
ele.style["border-color"] = "#ccc";
});
postRender(d, button, ele, fm);
return ele;
};
function renderSelection() {
for (let o of fm.value) {
if (
![...fm.output.childNodes]
.map((d) => {
let data = d.firstChild?.data?.trim();
return isNaN(+data) ? data : +data;
})
.includes(attr(o))
) {
fm.output.appendChild(renderSelected(o));
}
}
Sortable.create(fm.output);
Sortable.utils.on(fm.output, "update", () => {
fm.value = [...fm.output.childNodes].map((a) =>
a.childNodes[0].nodeValue.trim()
);
fm.dispatchEvent(new Event("input", { bubbles: true }));
});
}
fm.input.value = "";
fm.value = value
? Array.isArray(value)
? value.filter((d) => optionsMap.has(d))
: [value]
: [];
fm.onsubmit = (e) => {
e.preventDefault();
addToSelected();
};
fm.input.addEventListener("input", function (e) {
e.stopPropagation();
console.log("input", e);
if (
e.inputType === "insertReplacementText" ||
e.inputType === undefined
) {
addToSelected();
}
});
renderSelection();
};
const form = input({
type: "text",
title,
description,
attributes: { disabled },
action: onAction,
form: html`
<form>
${label ? `<label>${label}</label>` : ""}
<input name="input" type="text" autocomplete="off"
placeholder="${
placeholder || ""
}" style="font-size: 1em;" list=${list}>
<datalist id="${list}">
${options.map((d) =>
Object.assign(html`<option>`, {
value: attr(d)
})
)}
</datalist>
<br/>
</form>
`
});
form.output.style["margin-left"] = "0px";
form.style["min-height"] = "2.5em";
return form;
}