Multiple, with chips
Chips, a limit, chosen options taken out of the list, and Backspace to undo the last one.
<form class="demo" onsubmit="event.preventDefault()">
<div class="demo-field">
<label class="demo-label" for="skills">Skills <span class="demo-hint">· up to 5</span></label>
<select id="skills" name="skills" multiple></select>
</div>
<p class="demo-out" id="out">Nothing chosen</p>
</form>
import { createSelect } from 'https://devix.pk/cdn/oss/select@1.0.0/index.js';
const skills = [
{ value: 'ts', label: 'TypeScript', group: 'Languages' },
{ value: 'php', label: 'PHP', group: 'Languages' },
{ value: 'go', label: 'Go', group: 'Languages' },
{ value: 'rust', label: 'Rust', group: 'Languages' },
{ value: 'react', label: 'React', group: 'Frameworks' },
{ value: 'vue', label: 'Vue', group: 'Frameworks' },
{ value: 'svelte', label: 'Svelte', group: 'Frameworks' },
{ value: 'laravel', label: 'Laravel', group: 'Frameworks' },
{ value: 'postgres', label: 'PostgreSQL', group: 'Data' },
{ value: 'mysql', label: 'MySQL', group: 'Data' },
{ value: 'redis', label: 'Redis', group: 'Data' },
];
const out = document.getElementById('out');
createSelect(document.getElementById('skills'), {
options: skills,
value: ['ts', 'laravel'],
maxSelected: 5,
searchable: true,
placeholder: 'Add a skill',
onChange: (values) => (out.textContent = values.length ? `${values.length} chosen — posts skills[]=${values.join(', ')}` : 'Nothing chosen'),
});
@import url('https://devix.pk/cdn/oss/select@1.0.0/select.min.css');