Select
A searchable select control with single or multiple values, lazy loading, remote filtering and lookup support.
import { Select } from "@schukai/monster/source/components/form/select.mjs";Introduction
The Monster Select is a searchable selection control for simple dropdowns, remote option lists and complex multi-select workflows. Use it when users need labels, filtering, lazy loading or lookup logic that goes beyond a native <select>.
When to use Select
- Use it for local and remote option sets: The control supports inline options, lazy loading, lookup requests and remote filtering.
- Use it for single and multiple values: The same component can cover compact dropdowns and richer token-style multi-select cases.
- Use it when labels and values differ: Lookup handling keeps selected values readable even when labels must be resolved later.
- Do not use it for plain yes/no toggles: For binary choices, a switch or checkbox-style control is usually clearer.
Key Features
- Search and filtering: Filter local options or switch to remote filtering when the dataset is too large to preload.
- Lazy loading and lookup: Load options on demand and resolve selected values back to labels when initial data is incomplete.
- Programmatic control: Configure values, option sources and behavior through documented options instead of custom DOM patches.
- Monster-aligned styling: The control integrates into forms while keeping token-based styling and accessibility behavior.
Typical mistakes
Do not mix local lazy loading and remote filtering without a clear server contract. If labels come from the server, make sure lookup configuration is present, otherwise users may only see raw IDs. For static, tiny option sets, a simpler native control may still be enough.
Select With Options
This is a simple select component filled with three options.
You can select one of them. You can also use the keyboard to navigate through the options. Press the Tab key to focus the select component.
Then use the Arrow Down key to open the options. Use the Arrow Up key to navigate to the previous option.
Press the Space key to select the focused option. With the ESC key you can close the options.
Javascript
import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// our dataset is an array of objects, each object represents a single country
const dataset = [
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]
// now wie define the mapping for the select element.
// you can use the ${} syntax to reference the properties of the dataset
// the label template is a string that will be used to generate the label for each option
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
// the value template is a string that will be used to generate the value for each option
select.setOption('mapping.valueTemplate', '${country-code}')
// now we import the dataset into the select element
select.importOptions(dataset);
// and finally we append the select element to the body
document.body.appendChild(select);<script type="module">import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// the label template is a string that will be used to generate the label for each option
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
// the value template is a string that will be used to generate the value for each option
select.setOption('mapping.valueTemplate', '${country-code}')
// now wie import the dataset into the select element
select.importOptions([
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]);
// and finally we append the select element to the body
document.getElementById('uGh7shox').appendChild(select);</script>HTML
<div id="uGh7shox">
</div>Stylesheet
/** no additional stylesheet is defined **/Select With HTML Options
This is a simple select component filled with three div-options.
In this example, a simple select element with three options is displayed. Unlike the example Select with Options, these options are not added via the importOptions() method, but are defined directly in the HTML code.
The value of the option is the index of the option, starting at 1. This value can be overridden using the attribute data-monster-value.
The label is the entire div container. This allows HTML elements to be used within the options.
Javascript
/** this example does not use an extra script **/HTML
<monster-select>
<!-- This Option has a value of 10 and the label is 10 -->
<div data-monster-value="10">10</div>
<!-- This Option has no value and the label is 20, the value will be the index of the option -->
<!-- In this case, the value will be 2 -->
<div>20</div>
<!-- This Option has a value of 30 and the label is 30 -->
<div data-monster-value="30" style="background-color:red;color:white">30 x <i>❤</i></div>
</monster-select>Stylesheet
/** no additional stylesheet is defined **/Multiple Selection
This example demonstrates how to create a select component with multiple selection. You must only change the type attribute of the select component to checkbox.
Javascript
import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// our dataset is an array of objects, each object represents a single country
const dataset = [
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]
// now wie define the mapping for the select element.
// you can use the ${} syntax to reference the properties of the dataset
// we set the type to checkbox
// the default type is radio (single select)
select.setOption('type', 'checkbox');
// the label template is a string that will be used to generate the label for each option
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
// the value template is a string that will be used to generate the value for each option
select.setOption('mapping.valueTemplate', '${country-code}')
// now we import the dataset into the select element
select.importOptions(dataset);
// and finally we append the select element to the body
document.body.appendChild(select);<script type="module">import '@schukai/monster/source/components/form/select.mjs';
const select = document.createElement('monster-select');
select.setOption('type', 'checkbox');
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
select.importOptions([
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]);
document.getElementById('uGh7sh43').appendChild(select);</script>HTML
<body></body>Stylesheet
/** no additional stylesheet is defined **/Filter
This example demonstrates how to create a select component with a filter. With the filter you can search for options.
Javascript
import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// our dataset is an array of objects, each object represents a single country
const dataset = [
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]
// With the filter mode set to options, the select element will filter the options based on the text entered by the user.
select.setOption('filter.mode', 'options');
// This defines the position of the filter. You can set it to either popper or inline.
select.setOption('filter.position', 'popper');
// we set the type to checkbox
// the default type is radio (single select)
select.setOption('type', 'checkbox');
// the label template is a string that will be used to generate the label for each option
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
// the value template is a string that will be used to generate the value for each option
select.setOption('mapping.valueTemplate', '${country-code}')
// now we import the dataset into the select element
select.importOptions(dataset);
// and finally we append the select element to the body
document.body.appendChild(select);<script type="module">import '@schukai/monster/source/components/form/select.mjs';
const select = document.createElement('monster-select');
select.setOption('type', 'checkbox');
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
select.setOption('filter.mode', 'options');
select.setOption('filter.position', 'popper');
select.importOptions([
{
"name": "United Kingdom",
"alpha-2": "GB",
"country-code": "826",
},
{
"name": "Sweden",
"alpha-2": "SE",
"country-code": "752",
},
{
"name": "Germany",
"alpha-2": "DE",
"country-code": "276",
}
]);
document.getElementById('uGh7sa17').appendChild(select);</script>HTML
<body></body>Stylesheet
/** no additional stylesheet is defined **/Fetch Options
In Monster, you can dynamically load options for a <monster-select> control by specifying a url option. This allows the control to fetch options from a remote source, rather than defining them statically in the HTML.
Javascript
import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// the url to fetch the options from
select.setOption('url', "/assets/examples/countries.json");
// now wie define the mapping for the select element.
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
// and finally we append the select element to the body
document.body.appendChild(select);<script type="module">import '@schukai/monster/source/components/form/select.mjs';
const select = document.createElement('monster-select');
select.setOption('url', "/assets/examples/countries.json");
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
document.getElementById('uGh7sh25').appendChild(select);</script>HTML
<body></body>Stylesheet
/** no additional stylesheet is defined **/Lazy Load
The lazyload feature is useful when you want to load a list of options only when the user interacts with the control, such as a select dropdown. This is different from loading options immediately when the component is rendered, as shown in the previous example.
Javascript
import '@schukai/monster/source/components/form/select.mjs';
// first we create the select element
const select = document.createElement('monster-select');
// then we set lazyLoad to true and specify the URL to fetch the options from
select.setOption('features.lazyLoad', true);
// and the url to fetch the options from
select.setOption('url', "/assets/examples/countries.json");
// now wie define the mapping for the select element.
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
// and finally we append the select element to the body
document.body.appendChild(select);<script type="module">import '@schukai/monster/source/components/form/select.mjs';
const select = document.createElement('monster-select');
select.setOption('features.lazyLoad', true);
select.setOption('url', "/assets/examples/countries.json");
select.setOption('mapping.labelTemplate', '${name} (${alpha-2})')
select.setOption('mapping.valueTemplate', '${country-code}')
document.getElementById('uGh7sh15').appendChild(select);</script>HTML
<body></body>Stylesheet
/** no additional stylesheet is defined **/Remote Filter
The advanced feature of Monster <monster-select> control is the remote filtering mode. This allows the control to fetch filtered options from a remote source based on the user’s input in the search field. Unlike the standard fetch or lazy load, options are not loaded initially but only after a search term is entered.
To enable the remote filtering mode, set the filter.mode attribute to remote and provide a url option. The remote filter will be activated when the user enters a value in the search field, and Monster will then fetch matching options from the specified endpoint.
In this example, unfortunately we don't filter the value “not real” to see the effect. To see it, you have to look at the url in the network panel in the developer tools.
Javascript
import '@schukai/monster/source/components/form/select.mjs';<script type="module">import '@schukai/monster/source/components/form/select.mjs';</script>HTML
<monster-select
data-monster-option-filter-mode="remote"
data-monster-option-filter-position="popper"
data-monster-option-features-lazyload="false"
data-monster-option-url="/assets/examples/countries.json?q={filter}"
data-monster-option-mapping-labeltemplate="${name}"
data-monster-option-mapping-valuetemplate="${id}">
</monster-select>Stylesheet
/** no additional stylesheet is defined **/Server Side Filtering With A Remote URL
The advanced feature of Monster <monster-select> control is the remote filtering mode. This allows the control to fetch filtered options from a remote source based on the user’s input in the search field. Unlike the standard fetch or lazy load, options are not loaded initially but only after a search term is entered.
To enable the remote filtering mode, set the filter.mode attribute to remote and provide a url option. The remote filter will be activated when the user enters a value in the search field, and Monster will then fetch matching options from the specified endpoint.
In this example, unfortunately we don't filter the value “not real” to see the effect. To see it, you have to look at the url in the network panel in the developer tools.
Javascript
import '@schukai/monster/source/components/form/select.mjs';<script type="module">import '@schukai/monster/source/components/form/select.mjs';</script>HTML
<monster-select
data-monster-option-filter-mode="remote"
data-monster-option-filter-position="popper"
data-monster-option-features-lazyload="false"
data-monster-option-url="/assets/examples/countries.json?q={filter}"
data-monster-option-mapping-labeltemplate="${name}"
data-monster-option-mapping-valuetemplate="${id}">
</monster-select>Stylesheet
/** no additional stylesheet is defined **/Server Side Filtering With Pagination
The advanced feature of Monster <monster-select> control is the remote filtering mode. This allows the control to fetch filtered options from a remote source based on the user’s input in the search field. Unlike the standard fetch or lazy load, options are not loaded initially but only after a search term is entered.
To enable the remote filtering mode, set the filter.mode attribute to remote and provide a url option. The remote filter will be activated when the user enters a value in the search field, and Monster will then fetch matching options from the specified endpoint.
In this example, unfortunately we don't filter the value “not real” to see the effect. To see it, you have to look at the url in the network panel in the developer tools.
Javascript
import '@schukai/monster/source/components/form/select.mjs';<script type="module">import '@schukai/monster/source/components/form/select.mjs';</script>HTML
<monster-select
data-monster-option-url="/example/?limit=5&page={page}&q={filter}"
data-monster-option-filter-mode="remote"
data-monster-option-filter-position="popper"
data-monster-option-filter-defaultValue=""
data-monster-option-features-showremoteinfo="true"
data-monster-option-remoteinfo-url="/example/?limit=1"
data-monster-option-mapping-currentpage="sys.pagination.currentPage"
data-monster-option-mapping-valuetemplate="${id}"
data-monster-option-mapping-labeltemplate="${full_name}"
data-monster-option-mapping-selector="dataset.*"
data-monster-option-mapping-objectsperpage="sys.pagination.objectsPerPage"
data-monster-option-mapping-total="sys.pagination.totalObjects"
>
</monster-select>Stylesheet
/** no additional stylesheet is defined **/Using A Summary Template For Selections
When using multi-select, the default view shows individual badges for each selection. You can switch to a more compact summary view by setting the templateMapping.selected option to the built-in summary template. This is ideal for situations with limited space.
Javascript
import {
Select,
getSummaryTemplate,
} from "@schukai/monster/source/components/form/select.mjs";
const select = document.createElement("monster-select");
// Enable multiple selections
select.setOption("type", "checkbox");
// Use the summary template instead of individual badges
select.setOption("templateMapping.selected", getSummaryTemplate());
const countryOptions = [
{ label: "Germany", value: "DE" },
{ label: "United States", value: "US" },
{ label: "France", value: "FR" },
{ label: "Japan", value: "JP" },
];
select.setOption("options", countryOptions);
// Pre-select some values to demonstrate the summary
select.value = "DE,JP,FR";
document.getElementById("container").appendChild(select);<script type="module">import {
Select,
getSummaryTemplate,
} from "@schukai/monster/source/components/form/select.mjs";
import { domReady } from "@schukai/monster/source/dom/ready.mjs";
domReady.then(() => {
const select = document.createElement("monster-select");
document.getElementById("ooMosh8w").appendChild(select);
select.setOption("type", "checkbox");
select.setOption("templateMapping.selected", getSummaryTemplate());
const countryOptions = [
{ label: "Germany", value: "DE" },
{ label: "United States", value: "US" },
{ label: "France", value: "FR" },
{ label: "Japan", value: "JP" },
];
select.setOption("options", countryOptions);
select.value = "DE,JP,FR";
});</script>HTML
<div id="container"></div>Stylesheet
/** no additional stylesheet is defined **/Component Design
This component is implemented using the Shadow DOM to encapsulate its internal structure and styling. The shadow root ensures that the component's internal elements are isolated from the rest of the webpage, preventing external styles or scripts from affecting its internal layout or behavior.
Shadow DOM and Accessibility
The Shadow DOM restricts direct access to the internal structure of the component. While this encapsulation ensures consistency in the component’s design and functionality, developers cannot directly manipulate or style the internal elements. To maintain accessibility, the component supports features like keyboard navigation, screen readers, and logical focus management.
Customizing Through Exported Parts
While the Shadow DOM restricts direct access, customization is made possible through exported parts. Specific parts of the component are explicitly marked for export, enabling developers to target and style them using CSS.
Available Part Attributes
control: Represents the main control area of the select component, including the trigger and dropdown container.popper: Targets the dropdown element, which displays the options for selection.option: Represents individual options within the dropdown list.inline-filter: Styles the inline input filter for quickly filtering options.badge: Applies to badges that represent selected options.remove-badge: Targets the remove icon or button for clearing individual selected options.
Below is an example of how to use the CSS part attributes to customize different sections of the component.
monster-select::part(control) {
border: 1px solid #ccc;
border-radius: 4px;
padding: 8px;
}
monster-select::part(popper) {
background-color: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
monster-select::part(option) {
padding: 6px 12px;
cursor: pointer;
}
monster-select::part(badge) {
background-color: #0078d4;
color: white;
padding: 4px 8px;
border-radius: 4px;
}
monster-select::part(remove-badge) {
cursor: pointer;
margin-left: 4px;
}
Explanation of the Example
monster-select::part(control): Customizes the main control area, adding padding and a border.monster-select::part(popper): Styles the dropdown container, including its background color and shadow.monster-select::part(option): Adds padding and hover styles to options within the dropdown.monster-select::part(badge): Styles badges representing selected options.monster-select::part(remove-badge): Customizes the appearance of the remove icon/button for badges.
Accessibility
The monster-select component follows accessibility best practices to ensure usability for all users. Features include:
- Support for keyboard navigation using
Arrow Up,Arrow Down,Enter, andEscapekeys. - Screen reader support through proper roles and ARIA attributes for interactive elements.
- Logical focus management to ensure smooth navigation through the component's options and filters.
By adhering to these accessibility standards, the monster-select component ensures an inclusive user experience across all devices and assistive technologies.
HTML Structure
<monster-select></monster-select>JavaScript Initialization
const element = document.createElement('monster-select');
document.body.appendChild(element);Exported
getSelectionTemplate, getSummaryTemplate, popperElementSymbol, SelectDerived from
CustomControlOptions
The Options listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class. Therefore, it inherits Options from these parent classes. If you cannot find a specific Options in this list, we recommend consulting the documentation of the CustomControl.
- since
- deprecated
Properties and Attributes
The Properties and Attributes listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class and ultimately from HTMLElement. Therefore, it inherits Properties and Attributes from these parent classes. If you cannot find a specific Properties and Attributes in this list, we recommend consulting the documentation of the CustomControl.
data-monster-options: Sets the configuration options for the collapse component when used as an HTML attribute.data-monster-option-[name]: Sets the value of the configuration option[name]for the collapse component when used as an HTML attribute.
Methods
The methods listed in this section are defined directly within the class. This class is derived from several parent classes, including the CustomElement class and ultimately from HTMLElement. Therefore, it inherits methods from these parent classes. If you cannot find a specific method in this list, we recommend consulting the documentation of the CustomControl.
Constructor
constructor()Behavioral methods
fetch(url)url{string|url}: URL to fetch the options
- {Promise}
reset()State query methods
value()- {string}
e = document.querySelector('monster-select'); console.log(e.value) // ↦ 1 // ↦ ['1','2']``value(value)value
{Error}unsupported type
monster-selectedthis event is fired when the selection is set
e = document.querySelector('monster-select'); e.value=1``Structural methods
getLastFetchedData()3.66.0- {*}
{Error}storeFetchedData is not enabled
setOption(path,value)pathvalue
Static methods
[instanceSymbol]()- {Symbol}
instanceof operator.formAssociated()- {boolean}
getCSSStyleSheet()- {CSSStyleSheet[]}
getTag()- {string}
Lifecycle methods
Lifecycle methods are called by the environment and are usually not intended to be called directly.
[assembleMethodSymbol]()- {Select}
connectedCallback()- {void}
disconnectedCallback()- {void}
Other methods
blur()calcAndSetOptionsDimension()- {Select}
click()3.27.0focus(options)3.27.0options
importOptions(data)data{array|object|map|set}: data
- {Select}
{Error}map is not iterable{Error}missing label configuration
monster-options-setthis event is fired when the options are set
Events
The component emits the following events:
monster-changemonster-changedmonster-options-set
this event is fired when the options are setmonster-selection-removedmonster-selection-clearedmonster-selected
this event is fired when the selection is setmonster-options-set
this event is fired when the options are set
For more information on how to handle events, see the mdn documentation.