Refactor M2M toggle functionality to synchronize button states and improve placeholder updates

This commit is contained in:
Ross
2025-10-20 12:06:10 +01:00
parent b680ae749f
commit 8f5ce830fe
@@ -157,32 +157,37 @@ missing_map: {{ item.missing_map|default:"{}" }}</pre>
// Toggle exclude: clicking a M2M button will add/remove a hidden input and update styles // Toggle exclude: clicking a M2M button will add/remove a hidden input and update styles
function setupToggle(btn){ function setupToggle(btn){
btn.addEventListener('click', function(){ btn.addEventListener('click', function(){
const idx = btn.dataset.idx;
const model = btn.dataset.model; const model = btn.dataset.model;
const value = btn.dataset.value; const value = btn.dataset.value;
const container = document.getElementById('exclude-container-' + idx);
const inputName = 'exclude_' + idx; // Find all buttons with same model+value and toggle them together
// check if an input for this value already exists document.querySelectorAll('.m2m-toggle').forEach(function(b){
const selector = 'input[data-model="' + model + '"][data-value="' + value + '"]'; if(b.dataset.model === model && b.dataset.value === value){
const existing = container ? container.querySelector(selector) : null; const idx2 = b.dataset.idx;
if(existing){ const container = document.getElementById('exclude-container-' + idx2);
// remove input and toggle style to outline const inputName = 'exclude_' + idx2;
existing.remove(); const existing = container ? container.querySelector('input[data-model="' + model + '"][data-value="' + value + '"]') : null;
btn.classList.remove('btn-outline-secondary'); if(existing){
btn.classList.remove('btn-secondary'); existing.remove();
btn.classList.add('btn-success'); b.classList.remove('btn-outline-secondary');
} else { b.classList.remove('btn-secondary');
const inp = document.createElement('input'); b.classList.add('btn-success');
inp.type = 'hidden'; } else {
inp.name = inputName; const inp = document.createElement('input');
inp.value = model + ':::' + value; inp.type = 'hidden';
inp.setAttribute('data-model', model); inp.name = inputName;
inp.setAttribute('data-value', value); inp.value = model + ':::' + value;
container.appendChild(inp); inp.setAttribute('data-model', model);
// set button to excluded appearance inp.setAttribute('data-value', value);
btn.classList.remove('btn-success'); container.appendChild(inp);
btn.classList.add('btn-outline-secondary'); b.classList.remove('btn-success');
} b.classList.add('btn-outline-secondary');
}
}
});
// Update empty placeholders after toggling
refreshEmptyPlaceholders();
}); });
} }
@@ -193,10 +198,11 @@ missing_map: {{ item.missing_map|default:"{}" }}</pre>
// Show '(none)' for empty groups // Show '(none)' for empty groups
function refreshEmptyPlaceholders(){ function refreshEmptyPlaceholders(){
document.querySelectorAll('.m2m-group').forEach(function(group){ document.querySelectorAll('.m2m-group').forEach(function(group){
const buttons = group.querySelectorAll('.m2m-toggle'); // consider a button 'active' only if it has the green btn-success class
const activeButtons = group.querySelectorAll('.m2m-toggle.btn-success');
const none = group.querySelector('.m2m-none'); const none = group.querySelector('.m2m-none');
if(!none) return; if(!none) return;
if(buttons.length === 0){ if(activeButtons.length === 0){
none.style.display = ''; none.style.display = '';
} else { } else {
none.style.display = 'none'; none.style.display = 'none';