Select dropdowns are a ubiquitous part of web forms and interfaces. Often, you may need to dynamically add, remove or update the options in a select element based on user input or external data. Fortunately, JavaScript provides some simple yet powerful methods to manipulate select elements on the fly.
In this comprehensive guide, we‘ll explore the various techniques available to dynamically add options to selects with JavaScript.
The Humble Select Element
Before we jump into the code, let‘s briefly go over some key aspects of the HTML <select>
element:
- The
<select>
element represents a control that provides a menu of options - The
<option>
elements inside it represent each available option - Options can be pre-populated statically in HTML, or generated dynamically
- Common use cases include category filters, sort orders, user settings etc.
Here‘s an example static select menu:
<select id="colors">
<option>Red</option>
<option>Green</option>
<option>Blue</option>
</select>
This renders a simple dropdown with 3 color options.
But what if we want to add more options, sort them, or populate them from a database? That‘s where JavaScript comes in handy.
Adding Options with InnerHTML
The simplest way to add options to a select is by directly inserting new <option>
tags into the select‘s innerHTML
:
const select = document.getElementById(‘colors‘);
select.innerHTML += ‘<option>Yellow</option>‘;
This will append a new ‘Yellow‘ option to the end.
However, this approach has some downsides:
- It overrides any existing dynamic options
- You have to manually handle HTML escaping
- Parsing/updating the DOM is slower
So while handy for a quick addition, other methods are preferable.
Creating Option Elements
For more control and better performance, we can create new <option>
elements and append them:
const select = document.getElementById(‘colors‘);
// Create element
const option = document.createElement(‘option‘);
// Set value and text
option.value = ‘yellow‘;
option.textContent = ‘Yellow‘;
// Append to select
select.appendChild(option);
The key steps are:
- Use
document.createElement()
to instantiate a new<option>
- Set its value and text properties
- Append as child via
appendChild()
This avoids innerHTML manipulation, maintains existing options, and gives full control over the new element.
We can simplify this further into a reusable function:
function addOption(select, value, text) {
const option = document.createElement(‘option‘);
option.value = value;
option.textContent = text;
select.appendChild(option);
}
// Usage:
addOption(select, ‘yellow‘, ‘Yellow‘);
Now adding options is easy.
And here‘s one way to add multiple options in a loop:
const colors = [
{value: ‘red‘, text: ‘Red‘},
{value: ‘green‘, text: ‘Green‘},
// ...
];
colors.forEach(color => {
addOption(select, color.value, color.text);
});
This keeps things tidy and maintainable.
Using Option Constructors
In addition to document.createElement()
, we can also use the built-in Option
constructor and options
collection to add items:
const select = document.getElementById(‘colors‘);
// Construct new option
const option = new Option(‘Yellow‘, ‘yellow‘);
// Add to collection
select.options.add(option);
And similarly for multiple options:
[
{text: ‘Red‘, value: ‘red‘},
// ...
].forEach(o => {
select.options.add(new Option(o.text, o.value));
});
The constructor approach can be a bit simpler, but otherwise works the same way as manual creation.
Adding Groups of Options
Often you may want to add entire sets of options from an array or API response.
We can extend our previous reusable function to handle this:
function addOptions(select, options) {
options.forEach(option => {
const opt = document.createElement(‘option‘);
opt.value = option.value;
opt.textContent = option.text;
select.appendChild(opt);
});
}
// Adding array of options:
addOptions(select, [
{text: ‘Red‘, value: ‘red‘},
{text: ‘Green‘, value: ‘green‘},
// ...
]);
This abstracts away the repetitive logic into a single call.
For dynamic dropdowns from API data, we‘d simply pass the API response to this function.
Clearing Existing Options
When updating dynamic dropdowns, you may wish to clear existing options first:
function clearOptions(select) {
// Loop from end to start
for (let i = select.options.length - 1; i >= 0; i--) {
select.remove(i);
}
}
// Usage:
clearOptions(select);
addOptions(select, [/*...*/]);
Here we loop backwards removing each item.
And an alternate approach if you can use jQuery:
$(‘#selectID‘).empty(); // Clear contents
Just be aware this clears event listeners too.
Supporting Older Browsers
For older browsers without Element.remove()
, we can fallback to:
function removeOption(select, index) {
// Delete from options collection
select.options[index] = null;
}
function clearOptions(select) {
// Alternative loop
for(let i = select.options.length; i >= 0; i--) {
removeOption(select, i); // Custom clear
}
}
This manually deletes items from the index without DOM involvement.
That covers most pre-modern browsers.
Sorting & Reordering
In addition to adding items, you can dynamically sort option order too.
For example, to sort options alphabetically:
function sortOptions(select, comparator) {
// Convert to array for sorting
const options = Array.from(select.options);
// Default compare by text
comparator = comparator || (a, b) => {
if (a.text < b.text) return -1;
if (a.text > b.text) return 1;
return 0;
}
options.sort(comparator);
// Empty and append in new order
select.innerHTML = ‘‘;
options.forEach(option => {
select.appendChild(option);
});
}
sortOptions(select); // Sort A-Z
This grabs all options into an array, custom sorts them, empties the original, then adds back in desired order.
The comparator lets you customize the logic, say for sorting by value.
You can combine with our other functions for full control over dynamic options.
Updating Option Text/Values
To update existing options, the simplest method is locating by index or value and adjusting properties:
Update by index
// Update 3rd option
select.options[2].textContent = ‘New Text‘;
select.options[2].value = ‘newVal‘;
Update by value
function updateOption(select, value, updated) {
// Find index
const index = [...select.options].findIndex(o => o.value == value);
select.options[index].textContent = updated.text;
select.options[index].value = updated.value;
}
// Usage
updateOption(select, ‘red‘, {
text: ‘Maroon‘,
value: ‘maroon‘
});
And of course jQuery has simpler syntax for updating by value too:
$(‘select option[value=red]‘).text(‘Maroon‘);
The index and value attributes give direct access to modify specific dropdown options.
Removing Options
We saw earlier how to clear all options. To remove a specific one instead:
By index
select.remove(1); // Remove 2nd option
By value
function removeOption(select, value) {
select.options[select.options.findIndex(o => o.value == value)] = null;
}
removeOption(select, ‘yellow‘);
And in jQuery:
$(‘select option[value=yellow]‘).remove();
Removing options dynamically gives you free control over available choices.
Persisting Changes
One final consideration is persistence. Any changes made with JavaScript will be reset once the page reloads.
This may be fine for contextual filters and temporary states.
But for options meant to persist across sessions, also handle saving them to localStorage or an API in addition to updating the dropdown.
For example:
function addOption(select, option) {
// Add to dropdown
// ...
// Also persist
const options = JSON.parse(localStorage.getItem(‘options‘)) || [];
options.push(option);
localStorage.setItem(‘options‘, JSON.stringify(options));
}
This will keep customizations next time the page loads.
Putting It All Together
In summary, here is a reusable SelectUpdater
class encapsulating everything in one place:
class SelectUpdater {
constructor(select) {
this.select = select;
}
// Add/remove etc...
addOption(option) {
// ...
}
removeOption(value) {
// ...
}
clearOptions() {
// ...
}
// Sorting
sortAlpha() {}
// Etc...
}
const select = document.getElementById(‘select‘);
const updater = new SelectUpdater(select);
updater.addOption(...);
The class abstracts complex option manipulation behind simple method calls.
We can then manage any aspect of options dynamically!
Conclusion
And there we have it – numerous approaches to add, update and modify <select>
options on the fly with JavaScript!
Key takeaways:
- Add new options via
createElement()
,Option
constructor orinnerHTML
- Loop through arrays/datasets for bulk additions
- Sort, clear and remove as needed
- Carefully update indexes or use values/IDs to modify specific entries
- Encapsulate logic into reusable functions/classes
Controlling select dropdowns dynamically opens up all sorts of possibilities like custom filters, search autocompletes, category management UIs and more!
Hopefully this guide provides a solid starting point for enhancing standard select inputs with custom JavaScript behaviour.
Let me know if you have any other select control tips!