Combobox and tags
Both are form controls: name, required, disabled, value, validity, dirty and touched, and they work in <form xo-submit> like a native field. The value is a string, or an array with multiple and for tags. Options come from <option> children, from el.options, or from the schema's enum. creatable lets people add a value that is not in the list; remote leaves filtering to you through the xo-search event.
Values:
<div class="split">
<xo-combobox id="demo-author" name="author" label="Author" placeholder="Choose an author">
<option value="1">Ada Lovelace</option>
<option value="2">Grace Hopper</option>
<option value="3">Barbara Liskov</option>
</xo-combobox>
<xo-combobox id="demo-topics" name="topics" label="Topics (several, new allowed)" multiple creatable>
<option value="web">Web</option>
<option value="data" selected>Data</option>
<option value="design">Design</option>
</xo-combobox>
<xo-tags id="demo-tags" name="keywords" label="Keywords" placeholder="Type and press Enter"></xo-tags>
</div>
<p class="hint">Values: <output id="combo-out"></output></p>// The combobox page: both are form controls, `value` is a string, or an array with `multiple` and for tags.
const $ = (selector) => document.querySelector(selector);
const report = () => {
$('#combo-out').textContent = JSON.stringify({ author: $('#demo-author').value, topics: $('#demo-topics').value, keywords: $('#demo-tags').value });
};
for (const id of ['#demo-author', '#demo-topics', '#demo-tags']) $(id).addEventListener('change', report);
report();Keys: ArrowDown and ArrowUp open and move (the focus stays in the input, aria-activedescendant follows), Enter picks, Escape closes, Backspace on an empty field removes the last chip. In tags, Enter or a comma adds the typed text. Enter never submits the form while the list is open.
In a generated form
<xo-form> draws a control for any field with a widget hint that is a tag name: xo-combobox, xo-tags, xo-richtext, or your own element built on XoControl.
{
"fields": {
"Page.topics": { "widget": "xo-combobox" },
"Page.keywords": { "widget": "xo-tags" },
"Page.role": { "widget": "xo-combobox" }
}
}"keywords": { "type": "array", "items": { "type": "string" }, "x-xoong-widget": "xo-tags" }