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
function setupToggle(btn){
btn.addEventListener('click', function(){
const idx = btn.dataset.idx;
const model = btn.dataset.model;
const value = btn.dataset.value;
const container = document.getElementById('exclude-container-' + idx);
const inputName = 'exclude_' + idx;
// check if an input for this value already exists
const selector = 'input[data-model="' + model + '"][data-value="' + value + '"]';
const existing = container ? container.querySelector(selector) : null;
if(existing){
// remove input and toggle style to outline
existing.remove();
btn.classList.remove('btn-outline-secondary');
btn.classList.remove('btn-secondary');
btn.classList.add('btn-success');
} else {
const inp = document.createElement('input');
inp.type = 'hidden';
inp.name = inputName;
inp.value = model + ':::' + value;
inp.setAttribute('data-model', model);
inp.setAttribute('data-value', value);
container.appendChild(inp);
// set button to excluded appearance
btn.classList.remove('btn-success');
btn.classList.add('btn-outline-secondary');
}
// Find all buttons with same model+value and toggle them together
document.querySelectorAll('.m2m-toggle').forEach(function(b){
if(b.dataset.model === model && b.dataset.value === value){
const idx2 = b.dataset.idx;
const container = document.getElementById('exclude-container-' + idx2);
const inputName = 'exclude_' + idx2;
const existing = container ? container.querySelector('input[data-model="' + model + '"][data-value="' + value + '"]') : null;
if(existing){
existing.remove();
b.classList.remove('btn-outline-secondary');
b.classList.remove('btn-secondary');
b.classList.add('btn-success');
} else {
const inp = document.createElement('input');
inp.type = 'hidden';
inp.name = inputName;
inp.value = model + ':::' + value;
inp.setAttribute('data-model', model);
inp.setAttribute('data-value', value);
container.appendChild(inp);
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
function refreshEmptyPlaceholders(){
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');
if(!none) return;
if(buttons.length === 0){
if(activeButtons.length === 0){
none.style.display = '';
} else {
none.style.display = 'none';