Files
Plataforma-de-desarrolladores/SIG.Web/Scripts/DropDownGrid.js
Jorge Luis caudillo esparza 6685ef63fb Initial commit
2026-07-14 11:15:57 -07:00

559 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function (window, document) {
'use strict';
var DropdownGrid = {};
var activeRoot = null;
var activeClone = null;
var selectionCounter = 1;
DropdownGrid.initAll = function () {
var grids = document.querySelectorAll('[data-dropdown-grid="true"]');
for (var i = 0; i < grids.length; i++) {
DropdownGrid.init(grids[i]);
}
};
DropdownGrid.init = function (root) {
if (!root)
return;
if (root.getAttribute('data-dropdown-grid-init') === 'true')
return;
root.setAttribute('data-dropdown-grid-init', 'true');
DropdownGrid.initializeSelectedOrder(root.querySelector('.dropdown-grid-table-box'));
var input = root.querySelector('[data-dropdown-search="true"]');
if (input) {
input.removeAttribute('readonly');
input.removeAttribute('disabled');
input.addEventListener('mousedown', function (e) {
e.stopPropagation();
});
input.addEventListener('click', function (e) {
e.stopPropagation();
if (activeRoot !== root) {
DropdownGrid.show(root, true);
}
});
input.addEventListener('focus', function () {
if (activeRoot !== root) {
DropdownGrid.show(root, true);
}
});
input.addEventListener('input', function () {
if (activeRoot !== root) {
DropdownGrid.show(root, false);
}
DropdownGrid.filter(root, input.value);
});
input.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
e.preventDefault();
DropdownGrid.hideAll(true);
input.blur();
}
});
}
root.addEventListener('click', function (e) {
e.stopPropagation();
var target = e.target;
if (target.classList.contains('dropdown-grid-chip-remove')) {
e.preventDefault();
DropdownGrid.removeValue(root, target.getAttribute('data-value'));
}
});
DropdownGrid.updateDisplay(root);
DropdownGrid.moveSelectedRowsTop(root.querySelector('.dropdown-grid-table-box'));
};
DropdownGrid.show = function (root, clearInput) {
var input = root.querySelector('[data-dropdown-search="true"]');
var originalGrid = root.querySelector('.dropdown-grid-table-box');
if (!input || !originalGrid)
return;
DropdownGrid.hideAll(false);
DropdownGrid.moveSelectedRowsTop(originalGrid);
activeRoot = root;
activeClone = originalGrid.cloneNode(true);
activeClone.classList.add('dropdown-grid-floating');
activeClone.setAttribute('data-dropdown-grid-floating', 'true');
activeClone.style.display = 'block';
document.body.appendChild(activeClone);
if (clearInput === true)
input.value = '';
DropdownGrid.positionClone(root);
DropdownGrid.bindCloneEvents(root, activeClone);
DropdownGrid.syncCloneFromOriginal(root, activeClone);
DropdownGrid.moveSelectedRowsTop(activeClone);
DropdownGrid.syncCloneFromOriginal(root, activeClone);
DropdownGrid.filter(root, input.value);
setTimeout(function () {
input.focus();
}, 0);
};
DropdownGrid.hideAll = function (restoreText) {
var rootToRestore = activeRoot;
var clones = document.querySelectorAll('[data-dropdown-grid-floating="true"]');
for (var i = 0; i < clones.length; i++) {
if (clones[i].parentNode)
clones[i].parentNode.removeChild(clones[i]);
}
if (restoreText === true && rootToRestore) {
DropdownGrid.restoreInputText(rootToRestore);
}
activeRoot = null;
activeClone = null;
};
DropdownGrid.positionClone = function (root) {
if (!activeClone)
return;
var input = root.querySelector('[data-dropdown-search="true"]');
if (!input)
return;
var rect = input.getBoundingClientRect();
activeClone.style.position = 'fixed';
activeClone.style.left = rect.left + 'px';
activeClone.style.top = (rect.bottom + 2) + 'px';
activeClone.style.minWidth = rect.width + 'px';
activeClone.style.zIndex = '999999';
};
DropdownGrid.bindCloneEvents = function (root, clone) {
clone.addEventListener('mousedown', function (e) {
e.stopPropagation();
});
clone.addEventListener('click', function (e) {
e.stopPropagation();
var target = e.target;
var row = DropdownGrid.getRow(target);
if (target.classList.contains('dropdown-grid-select-all')) {
setTimeout(function () {
DropdownGrid.cloneSelectAllChanged(root, clone, target.checked);
}, 0);
return;
}
if (!row)
return;
var check = row.querySelector('.dropdown-grid-check');
if (!check)
return;
if (target !== check) {
e.preventDefault();
check.checked = !check.checked;
}
setTimeout(function () {
DropdownGrid.applyValue(root, check.value, check.checked);
}, 0);
});
};
DropdownGrid.applyValue = function (root, value, checked) {
var multiple = root.getAttribute('data-multiple') === 'true';
var originalGrid = root.querySelector('.dropdown-grid-table-box');
if (!originalGrid)
return;
if (!multiple && checked) {
DropdownGrid.setAllChecks(originalGrid, false);
if (activeRoot === root && activeClone) {
DropdownGrid.setAllChecks(activeClone, false);
}
}
var realCheck = originalGrid.querySelector(
'.dropdown-grid-check[value="' + cssEscape(value) + '"]'
);
if (realCheck) {
realCheck.checked = checked;
var realRow = DropdownGrid.getRow(realCheck);
if (checked && realRow) {
realRow.setAttribute('data-selected-order', selectionCounter++);
} else if (realRow) {
realRow.removeAttribute('data-selected-order');
}
}
DropdownGrid.refreshHidden(root);
DropdownGrid.updateDisplay(root);
DropdownGrid.moveSelectedRowsTop(originalGrid);
if (activeRoot === root && activeClone) {
DropdownGrid.rebuildClone(root);
var input = root.querySelector('[data-dropdown-search="true"]');
if (input)
DropdownGrid.filter(root, input.value);
}
};
DropdownGrid.rebuildClone = function (root) {
var originalGrid = root.querySelector('.dropdown-grid-table-box');
if (!originalGrid || !activeClone)
return;
var oldClone = activeClone;
activeClone = originalGrid.cloneNode(true);
activeClone.classList.add('dropdown-grid-floating');
activeClone.setAttribute('data-dropdown-grid-floating', 'true');
activeClone.style.display = 'block';
if (oldClone.parentNode) {
oldClone.parentNode.replaceChild(activeClone, oldClone);
} else {
document.body.appendChild(activeClone);
}
DropdownGrid.positionClone(root);
DropdownGrid.bindCloneEvents(root, activeClone);
DropdownGrid.syncCloneFromOriginal(root, activeClone);
DropdownGrid.moveSelectedRowsTop(activeClone);
DropdownGrid.syncCloneFromOriginal(root, activeClone);
};
DropdownGrid.setAllChecks = function (container, checked) {
if (!container)
return;
var checks = container.querySelectorAll('.dropdown-grid-check');
for (var i = 0; i < checks.length; i++) {
checks[i].checked = checked;
var row = DropdownGrid.getRow(checks[i]);
if (row)
row.removeAttribute('data-selected-order');
}
};
DropdownGrid.getRow = function (target) {
while (target && target !== document) {
if (target.tagName && target.tagName.toLowerCase() === 'tr')
return target;
target = target.parentNode;
}
return null;
};
DropdownGrid.cloneSelectAllChanged = function (root, clone, checked) {
var cloneRows = clone.querySelectorAll('tbody tr');
for (var i = 0; i < cloneRows.length; i++) {
if (cloneRows[i].style.display === 'none')
continue;
var cloneCheck = cloneRows[i].querySelector('.dropdown-grid-check');
if (!cloneCheck)
continue;
DropdownGrid.applyValue(root, cloneCheck.value, checked);
}
DropdownGrid.refreshHidden(root);
DropdownGrid.updateDisplay(root);
DropdownGrid.moveSelectedRowsTop(root.querySelector('.dropdown-grid-table-box'));
if (activeClone) {
DropdownGrid.rebuildClone(root);
}
};
DropdownGrid.syncCloneFromOriginal = function (root, clone) {
if (!clone)
return;
var originalChecks = root.querySelectorAll('.dropdown-grid-table-box .dropdown-grid-check');
for (var i = 0; i < originalChecks.length; i++) {
var cloneCheck = clone.querySelector(
'.dropdown-grid-check[value="' + cssEscape(originalChecks[i].value) + '"]'
);
if (!cloneCheck)
continue;
cloneCheck.checked = originalChecks[i].checked;
var originalRow = DropdownGrid.getRow(originalChecks[i]);
var cloneRow = DropdownGrid.getRow(cloneCheck);
if (originalRow && cloneRow) {
var order = originalRow.getAttribute('data-selected-order');
if (order)
cloneRow.setAttribute('data-selected-order', order);
else
cloneRow.removeAttribute('data-selected-order');
}
}
};
DropdownGrid.initializeSelectedOrder = function (container) {
if (!container)
return;
var checks = container.querySelectorAll('.dropdown-grid-check:checked');
for (var i = 0; i < checks.length; i++) {
var row = DropdownGrid.getRow(checks[i]);
if (row && !row.getAttribute('data-selected-order')) {
row.setAttribute('data-selected-order', selectionCounter++);
}
}
};
DropdownGrid.moveSelectedRowsTop = function (container) {
if (!container)
return;
var tbody = container.querySelector('tbody');
if (!tbody)
return;
var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr'));
var selected = [];
var unselected = [];
for (var i = 0; i < rows.length; i++) {
var check = rows[i].querySelector('.dropdown-grid-check');
if (check && check.checked)
selected.push(rows[i]);
else
unselected.push(rows[i]);
}
selected.sort(function (a, b) {
var ao = parseInt(a.getAttribute('data-selected-order') || '0', 10);
var bo = parseInt(b.getAttribute('data-selected-order') || '0', 10);
return bo - ao;
});
for (var s = 0; s < selected.length; s++) {
tbody.appendChild(selected[s]);
}
for (var u = 0; u < unselected.length; u++) {
tbody.appendChild(unselected[u]);
}
};
DropdownGrid.filter = function (root, value) {
value = (value || '').toLowerCase();
var container = activeRoot === root && activeClone
? activeClone
: root.querySelector('.dropdown-grid-table-box');
if (!container)
return;
var rows = container.querySelectorAll('tbody tr');
for (var i = 0; i < rows.length; i++) {
var search = rows[i].getAttribute('data-search') || '';
rows[i].style.display = search.indexOf(value) >= 0 ? '' : 'none';
}
};
DropdownGrid.refreshHidden = function (root) {
var hidden = root.querySelector('input[type="hidden"]');
var checks = root.querySelectorAll('.dropdown-grid-table-box .dropdown-grid-check:checked');
var selected = [];
for (var i = 0; i < checks.length; i++) {
selected.push(checks[i].value);
}
if (hidden)
hidden.value = selected.join(',');
};
DropdownGrid.removeValue = function (root, value) {
DropdownGrid.applyValue(root, value, false);
};
DropdownGrid.updateDisplay = function (root) {
var hidden = root.querySelector('input[type="hidden"]');
var input = root.querySelector('[data-dropdown-search="true"]');
var chips = root.querySelector('.dropdown-grid-chips');
if (!hidden)
return;
var multiple = root.getAttribute('data-multiple') === 'true';
var values = hidden.value ? hidden.value.split(',') : [];
if (!multiple || values.length <= 1) {
if (chips) {
chips.innerHTML = '';
chips.style.display = 'none';
}
if (input && activeRoot !== root) {
if (values.length === 1) {
var row = root.querySelector(
'.dropdown-grid-table-box tr[data-key="' + cssEscape(values[0]) + '"]'
);
input.value = row ? row.getAttribute('data-text') || '' : '';
} else {
input.value = '';
}
}
return;
}
if (input && activeRoot !== root)
input.value = '';
if (!chips)
return;
chips.innerHTML = '';
chips.style.display = '';
for (var i = 0; i < values.length; i++) {
var rowChip = root.querySelector(
'.dropdown-grid-table-box tr[data-key="' + cssEscape(values[i]) + '"]'
);
if (!rowChip)
continue;
var text = rowChip.getAttribute('data-text') || values[i];
var chip = document.createElement('span');
chip.className = 'dropdown-grid-chip';
var label = document.createElement('span');
label.innerHTML = text;
var remove = document.createElement('a');
remove.href = '#';
remove.className = 'dropdown-grid-chip-remove';
remove.setAttribute('data-value', values[i]);
remove.innerHTML = ' ×';
chip.appendChild(label);
chip.appendChild(remove);
chips.appendChild(chip);
}
};
DropdownGrid.restoreInputText = function (root) {
var hidden = root.querySelector('input[type="hidden"]');
var input = root.querySelector('[data-dropdown-search="true"]');
if (!hidden || !input)
return;
var values = hidden.value ? hidden.value.split(',') : [];
if (values.length === 1) {
var row = root.querySelector(
'.dropdown-grid-table-box tr[data-key="' + cssEscape(values[0]) + '"]'
);
input.value = row ? row.getAttribute('data-text') || '' : '';
} else {
input.value = '';
}
};
function cssEscape(value) {
if (window.CSS && CSS.escape)
return CSS.escape(value);
return String(value).replace(/["\\]/g, '\\$&');
}
document.addEventListener('mousedown', function (e) {
if (activeRoot && activeRoot.contains(e.target))
return;
if (activeClone && activeClone.contains(e.target))
return;
DropdownGrid.hideAll(true);
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
DropdownGrid.hideAll(true);
}
});
window.addEventListener('resize', function () {
if (activeRoot && activeClone)
DropdownGrid.positionClone(activeRoot);
});
window.addEventListener('scroll', function () {
if (activeRoot && activeClone)
DropdownGrid.positionClone(activeRoot);
}, true);
window.DropdownGrid = DropdownGrid;
})(window, document);