Виджет для формы выбора зеркал
This commit is contained in:
120
dbapp/mainapp/static/js/checkbox-select-multiple.js
Normal file
120
dbapp/mainapp/static/js/checkbox-select-multiple.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Checkbox Select Multiple Widget
|
||||
* Provides a multi-select dropdown with checkboxes and tag display
|
||||
*/
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize all checkbox multiselect widgets
|
||||
document.querySelectorAll('.checkbox-multiselect-wrapper').forEach(function(wrapper) {
|
||||
initCheckboxMultiselect(wrapper);
|
||||
});
|
||||
});
|
||||
|
||||
function initCheckboxMultiselect(wrapper) {
|
||||
const widgetId = wrapper.dataset.widgetId;
|
||||
const inputContainer = wrapper.querySelector('.multiselect-input-container');
|
||||
const searchInput = wrapper.querySelector('.multiselect-search');
|
||||
const dropdown = wrapper.querySelector('.multiselect-dropdown');
|
||||
const tagsContainer = wrapper.querySelector('.multiselect-tags');
|
||||
const clearButton = wrapper.querySelector('.multiselect-clear');
|
||||
const checkboxes = wrapper.querySelectorAll('input[type="checkbox"]');
|
||||
|
||||
// Show dropdown when clicking on input container
|
||||
inputContainer.addEventListener('click', function(e) {
|
||||
if (e.target !== clearButton) {
|
||||
positionDropdown();
|
||||
dropdown.classList.add('show');
|
||||
searchInput.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Position dropdown (up or down based on available space)
|
||||
function positionDropdown() {
|
||||
const rect = inputContainer.getBoundingClientRect();
|
||||
const spaceAbove = rect.top;
|
||||
const spaceBelow = window.innerHeight - rect.bottom;
|
||||
const dropdownHeight = 300; // max-height from CSS
|
||||
|
||||
// If more space below and enough space, open downward
|
||||
if (spaceBelow > spaceAbove && spaceBelow >= dropdownHeight) {
|
||||
dropdown.classList.add('dropdown-below');
|
||||
} else {
|
||||
dropdown.classList.remove('dropdown-below');
|
||||
}
|
||||
}
|
||||
|
||||
// Hide dropdown when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!wrapper.contains(e.target)) {
|
||||
dropdown.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Search functionality
|
||||
searchInput.addEventListener('input', function() {
|
||||
const searchTerm = this.value.toLowerCase();
|
||||
const options = wrapper.querySelectorAll('.multiselect-option');
|
||||
|
||||
options.forEach(function(option) {
|
||||
const label = option.querySelector('.option-label').textContent.toLowerCase();
|
||||
if (label.includes(searchTerm)) {
|
||||
option.classList.remove('hidden');
|
||||
} else {
|
||||
option.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Handle checkbox changes
|
||||
checkboxes.forEach(function(checkbox) {
|
||||
checkbox.addEventListener('change', function() {
|
||||
updateTags();
|
||||
});
|
||||
});
|
||||
|
||||
// Clear all button
|
||||
clearButton.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
checkboxes.forEach(function(checkbox) {
|
||||
checkbox.checked = false;
|
||||
});
|
||||
updateTags();
|
||||
});
|
||||
|
||||
// Update tags display
|
||||
function updateTags() {
|
||||
tagsContainer.innerHTML = '';
|
||||
let hasSelections = false;
|
||||
|
||||
checkboxes.forEach(function(checkbox) {
|
||||
if (checkbox.checked) {
|
||||
hasSelections = true;
|
||||
const tag = document.createElement('div');
|
||||
tag.className = 'multiselect-tag';
|
||||
tag.innerHTML = `
|
||||
<span>${checkbox.dataset.label}</span>
|
||||
<button type="button" class="multiselect-tag-remove" data-value="${checkbox.value}">×</button>
|
||||
`;
|
||||
|
||||
// Remove tag on click
|
||||
tag.querySelector('.multiselect-tag-remove').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
checkbox.checked = false;
|
||||
updateTags();
|
||||
});
|
||||
|
||||
tagsContainer.appendChild(tag);
|
||||
}
|
||||
});
|
||||
|
||||
// Show/hide clear button
|
||||
if (hasSelections) {
|
||||
inputContainer.classList.add('has-selections');
|
||||
} else {
|
||||
inputContainer.classList.remove('has-selections');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize tags on load
|
||||
updateTags();
|
||||
}
|
||||
Reference in New Issue
Block a user