Vanilla JS select enhancer core (no framework integration)
npm install selectameloselectamelo is a vanilla JavaScript component that enhances a standard
HTML element (single or multiple) into a modern, accessible and dynamic select.
It does not use jQuery, does not depend on UI frameworks, and keeps the original in the DOM to preserve native form submission and backend compatibility.
---
- Single and multiple select
- Built-in search
- Clear button (X)
- Multiple select with removable chips
- Full keyboard navigation (↑ ↓ Enter Esc Tab Backspace)
- Dynamic option management
- Native HTML disabled
- Simulated readonly (non-editable but still submitted)
- Custom events (zselect:*)
- 100% Vanilla JS
---
bash
npm install selectamelo
`$3
`bash
npm run build
`---
Basic usage
$3
`html
`$3
`js
import { Selectamelo } from "selectamelo";const select = document.querySelector("#role");
Selectamelo.create(select, {
placeholder: "Select a role"
});
`---
Options
`ts
type SelectameloOptions = {
searchable?: boolean; // default true
placeholder?: string; // default ""
allowClear?: boolean; // default true
hideSearch?: boolean; // default false disabled?: boolean; // disables the select (NOT submitted)
readonly?: boolean; // locks UI but value is submitted
};
`$3
| State | Interaction | Submit |
|----------|-------------|--------|
| disabled | ❌ | ❌ |
| readonly | ❌ | ✅ |
HTML-driven options are also supported:
`html
data-allow-clear="true"
data-hide-search="true"
data-searchable="false"
data-readonly="true"
>
`---
Instance API
$3
`js
const inst = Selectamelo.create(select);
const same = Selectamelo.get(select);
`---
$3
`js
inst.getValue(); // string | string[]
inst.setValue("admin"); // single
inst.setValue(["1","2"]); // multiple
inst.setValue(null); // reset
`---
$3
`js
inst.open();
inst.close();
`---
$3
`js
inst.setDisabled(true);
inst.setDisabled(false);inst.setReadonly(true);
inst.setReadonly(false);
inst.isDisabled(); // boolean
inst.isReadonly(); // boolean
`---
$3
Temporarily blocks UI interaction.
`js
inst.setLoading(true);
inst.setLoading(false);
`---
Dynamic option management
$3
`js
inst.clearOptions(true); // keep placeholder
`---
$3
`js
inst.setOptions(
[
{ value: "1", label: "Rome" },
{ value: "2", label: "Tivoli", disabled: true }
],
true
);
`---
$3
`js
inst.addOption({ value: "3", label: "Latina" });
`$3
`js
inst.addOption({ value: "3", label: "Latina" }, true);
`---
$3
`js
inst.removeOption("2");
`---
$3
`js
inst.updateOption("1", { label: "Rome (RM)" });
inst.updateOption("2", { disabled: false });
`---
$3
`js
inst.upsertOption({ value: "9", label: "Frosinone" });
inst.upsertOption({ value: "9", label: "Frosinone (FR)" });
`---
Custom events
Events are emitted on the original