I'm using Tom Select with a multi-select dropdown for a folder structure where options are grouped by parent folders. For example, if I select a top-level folder like app
, I want any child options like app/Helpers
or app/Http
to automatically be disabled, preventing them from being selected.
Here's the current setup:
checkbox_options
plugin.select
field includes optgroup
elements, and options have data-groups
attributes to indicate their parent grouping.HTML Structure:
<select id="myFolders" name="folders[]" multiple autocomplete="off">
<optgroup label="app">
<option value="app" selected>app</option>
<option value="app/Helpers">app/Helpers</option>
<option value="app/Http">app/Http</option>
</optgroup>
</select>
Javascript I tried.
const tomSelect = new TomSelect('#myFolders', {
plugins: {
'checkbox_options': {
'checkedClassNames': ['ts-checked'],
'uncheckedClassNames': ['ts-unchecked'],
'className': 'form-check-input'
},
'remove_button': {
title:'Remove this item',
}
},
onChange: function () {
updateDisabledOptions(this);
}
});
function updateDisabledOptions(tomSelectInstance) {
const selectedValues = tomSelectInstance.getValue();
const selectedGroups = new Set(selectedValues);
Object.values(tomSelectInstance.options).forEach(option => {
const optionElement = document.querySelector(`.ts-dropdown [data-value="${option.value}"]`);
if (optionElement) {
const checkbox = optionElement.querySelector('.form-check-input');
if (checkbox) {
const isChildOfSelectedGroup = Array.from(selectedGroups).some(
group => option.value.startsWith(group + '/')
);
if (isChildOfSelectedGroup) {
optionElement.classList.add('disabled');
checkbox.setAttribute('disabled', true);
} else {
optionElement.classList.remove('disabled');
checkbox.removeAttribute('disabled');
}
}
}
});
}
Problem: The function is adding the disabled
attribute to child checkboxes, but it doesn’t prevent them from being selected. Even with aria-disabled
and disabled
attributes set, the checkboxes are still selectable.
Expected Outcome: If a parent folder like app
is selected, any child folders (e.g., app/Helpers
) should be automatically disabled
and not selectable.
Questions:
Tom Select
when their parent is selected?Tom Select
to achieve this?Any suggestions or code modifications are welcome! Thank you in advance.
The jsFiddle link Here
(No Jquery)
thanks, @La Ngoc, I changed the function updateDisbaledOptions
when the child selected and later user select the parent the selected child will be auto removed. here is the final function.. maybe helpful for others.
const updateDisabledOptions = (tomSelectInstance) => {
const selectedValues = tomSelectInstance.getValue();
const parents = [...Object.values(tomSelectInstance.optgroups)].map(o => o.label);
parents.forEach(parent => {
const options = [...Object.values(tomSelectInstance.options)];
const children = options.filter(option => option.value.startsWith(`${parent}/`));
children.forEach(child => {
if (selectedValues.includes(parent)) {
tomSelectInstance.removeItem(child.value);
tomSelectInstance.updateOption(child.value, {
value: child.value,
text: child.text,
disabled: true,
});
} else {
tomSelectInstance.updateOption(child.value, {
value: child.value,
text: child.text,
disabled: false,
});
}
});
});
};