我正在使用 TomSelect 在我的项目中创建一个多选下拉列表。我添加了“全选”选项,并试图确保它始终显示为下拉列表中的第一项。然而,尽管我做出了努力,“全选”选项并不总是出现在列表顶部。
这是我当前的实现:
function renderOptionItem(item, escape) {
let img = item.src ? `<img class="me-2 tomselect-image" src="${escape(item.src)}" alt="icon" />` : '';
let subtext = item.subtext ? `<div class="text-muted">${escape(item.subtext)}</div>` : '';
return `<div class="d-flex align-items-center">
${img}
<div>
<div>${escape(item.text)}</div>
${subtext}
</div>
</div>`;
}
function updateSelectedItemsLabel(tomSelectInstance) {
const selectedItems = tomSelectInstance.getValue();
const selectedCount = selectedItems.length;
const control = tomSelectInstance.control.querySelector('.items');
if (selectedCount > 3 && control) {
// Clear the control and add the summary item
control.innerHTML = `<div class="item">Valgt ${selectedCount} elementer</div>`;
} else {
tomSelectInstance.refreshItems(); // Refresh to show actual selected items
}
// Update the "Select all" checkbox state
const selectAllCheckbox = tomSelectInstance.dropdown_content.querySelector('.option[data-value="select-all"] input[type="checkbox"]');
if (selectAllCheckbox) {
const allItemValues = Object.keys(tomSelectInstance.options).filter(value => value !== 'select-all');
selectAllCheckbox.checked = selectedItems.length === allItemValues.length;
// Set a specific ID to the checkbox
selectAllCheckbox.id = 'groupSelect-opt-0'; // Replace 'your-specific-id' with the desired ID
}
}
function handleSelectAll(tomSelectInstance) {
const allItems = tomSelectInstance.options;
const allItemValues = Object.keys(allItems).filter(value => value !== 'select-all');
const selectedItems = tomSelectInstance.getValue();
if (selectedItems.length === allItemValues.length) {
tomSelectInstance.clear(); // Deselect all if already selected
} else {
tomSelectInstance.setValue(allItemValues); // Select all
}
}
function initializeTomSelect(selector, isSingleSelect = false) {
const tomSelectInstance = new TomSelect(selector, {
valueField: 'value',
labelField: 'text',
searchField: ['text', 'subtext'],
render: {
option: (item, escape) => {
if (item.value === 'select-all') {
return `<div class="d-flex align-items-center option">
<div>Vælg alle</div>
</div>`;
} else {
return renderOptionItem(item, escape);
}
},
item: renderOptionItem
},
plugins: {
'remove_button': {},
'dropdown_input': {},
'checkbox_options': {},
'clear_button': {
title: 'Ryd valgte' // Danish for "Clear selected"
},
},
maxItems: isSingleSelect ? 1 : null,
placeholder: isSingleSelect ? 'Vælg en mulighed...' : 'Vælg nogle muligheder...',
create: false,
allowEmptyOption: false, // Disallow empty options
onInitialize: function() {
if (isSingleSelect) {
this.clear(); // Ensure no default selection
}
updateSelectedItemsLabel(this);
// Add "Select all" option first
this.addOption({ value: 'select-all', text: 'Vælg alle' });
this.refreshOptions(false);
// Ensure "Select all" is the first item
const dropdownContent = this.dropdown_content;
const selectAllOption = this.getOption('select-all');
if (selectAllOption) {
dropdownContent.insertBefore(selectAllOption, dropdownContent.firstChild);
}
dropdownContent.addEventListener('click', (event) => {
const optionElement = event.target.closest('.option');
if (optionElement && optionElement.getAttribute('data-value') === 'select-all') {
event.stopPropagation(); // Prevent the dropdown from closing
handleSelectAll(this);
updateSelectedItemsLabel(this);
}
});
},
onItemAdd: function(value) {
if (value !== 'select-all') {
updateSelectedItemsLabel(this);
}
},
onItemRemove: function() {
updateSelectedItemsLabel(this);
}
});
function moveSelectAllToTop(instance) {
const dropdownContent = instance.dropdown_content;
const selectAllOption = instance.getOption('select-all');
if (selectAllOption) {
dropdownContent.insertBefore(selectAllOption, dropdownContent.firstChild);
}
}
// Handle the clear button functionality
tomSelectInstance.on('clear', function() {
tomSelectInstance.refreshItems();
});
// Handle changes to re-enable item removal if more than 3 selected
tomSelectInstance.on('change', function() {
const selectedItems = tomSelectInstance.getValue();
const control = tomSelectInstance.control.querySelector('.items');
if (selectedItems.length <= 3 && control && control.innerHTML.includes('elementer')) {
tomSelectInstance.refreshItems(); // Refresh to show actual selected items
}
// Update the "Select all" checkbox state
const selectAllCheckbox = tomSelectInstance.dropdown_content.querySelector('.option[data-value="select-all"] input[type="checkbox"]');
if (selectAllCheckbox) {
const allItemValues = Object.keys(tomSelectInstance.options).filter(value => value !== 'select-all');
selectAllCheckbox.checked = selectedItems.length === allItemValues.length;
}
});
}
// Initialize Tom Select elements
document.addEventListener('DOMContentLoaded', function() {
initializeTomSelect('#employeeSelect');
initializeTomSelect('#entryTypeSelect', true); // Set isSingleSelect to true for entryTypeSelect
});
问题 尽管有上面的代码片段,“全选”选项并不总是显示为下拉列表中的第一项。我尝试过以下方法:
但是,这些方法并不总是导致“全选”选项位于顶部。
预期行为 每当打开下拉列表时,“全选”选项应始终显示为下拉列表中的第一项。
请求帮助 我正在寻找有关如何确保“全选”选项始终出现在下拉列表顶部的指南。任何有关如何实现这一目标的见解或建议将不胜感激。
为了确保“全选”选项始终显示为 TomSelect 下拉列表中的第一项,您应该在初始化期间以及刷新选项时处理其位置。这是基于现有代码的简化方法:
初始化(onInitialize函数):
使用 this.addOption() 方法添加“全选”选项。 立即使用 this.refreshOptions(false) 刷新选项以反映新添加的内容。 使用 insertBefore() 将“全选”选项移动到下拉内容的顶部。 将“全选”移至顶部功能:
定义一个函数(moveSelectAllToTop)以确保“全选”选项始终位于下拉内容的第一位。 在初始化期间以及刷新选项时调用此函数(onInitialize和refreshOptions)。 您可以通过以下方式调整代码来实现此目的:
function initializeTomSelect(selector, isSingleSelect = false) {
const tomSelectInstance = new TomSelect(selector, {
// Your existing configuration...
onInitialize: function() {
if (isSingleSelect) {
this.clear(); // Ensure no default selection
}
// Add "Select all" option and ensure it's at the top
this.addOption({ value: 'select-all', text: 'Vælg alle' });
this.refreshOptions(false); // Refresh options immediately
moveSelectAllToTop(this); // Ensure "Select all" is the first item
// Other initialization logic...
},
// Other event handlers...
onItemAdd: function(value) {
if (value !== 'select-all') {
updateSelectedItemsLabel(this);
}
},
onItemRemove: function() {
updateSelectedItemsLabel(this);
}
});
// Function to move "Select All" to the top of dropdown content
function moveSelectAllToTop(instance) {
const dropdownContent = instance.dropdown_content;
const selectAllOption = instance.getOption('select-all');
if (selectAllOption) {
dropdownContent.insertBefore(selectAllOption, dropdownContent.firstChild);
}
}
// Additional event listeners and handlers...
// Initialize TomSelect instance
// Ensure proper initialization for all instances
}
// Initialize Tom Select elements
document.addEventListener('DOMContentLoaded', function() {
initializeTomSelect('#employeeSelect');
initializeTomSelect('#entryTypeSelect', true); // Set isSingleSelect to true for entryTypeSelect
});
说明:
onInitialize 函数:当 TomSelect 实例初始化时,添加“全选”选项并立即刷新选项(refreshOptions(false))。然后,您调用 moveSelectAllToTop(this) 以确保该选项位于顶部。
moveSelectAllToTop 函数:该函数使用insertBefore()将“全选”选项移动到下拉内容(dropdownContent)的顶部。它检查选项是否存在(getOption('select-all')),然后将其放置在 dropdownContent 中的第一个子元素之前。
通过以这种方式构建初始化和选项管理,您可以确保“全选”选项在打开或刷新时始终显示为下拉列表中的第一项。此方法应该可以解决您在 TomSelect 下拉列表中定位“全选”选项时遇到的问题。