function createToastContainer() {
const container = document.createElement('div');
container.id = 'toastContainer';
container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
document.body.appendChild(container);
return container;
}
// Simple toast helper
function showToast(message, type) {
const toastContainer = document.getElementById('toastContainer') || createToastContainer();
const toast = document.createElement('div');
toast.className = `toast align-items-center text-white bg-${type} border-0`;
toast.role = 'alert';
toast.innerHTML = `
`;
toastContainer.appendChild(toast);
const bsToast = new bootstrap.Toast(toast, { delay: 3000 });
bsToast.show();
toast.addEventListener('hidden.bs.toast', () => toast.remove());
}
function downloadBarcode(svgId, filename = "barcode.png") {
const svg = document.getElementById(svgId);
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svg);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// Optionally set canvas size
const bbox = svg.getBBox();
canvas.width = bbox.width + 20; // padding
canvas.height = bbox.height + 20;
const img = new Image();
const svgBlob = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svgBlob);
img.onload = () => {
ctx.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
const pngUrl = canvas.toDataURL("image/png");
const a = document.createElement("a");
a.href = pngUrl;
a.download = filename;
a.click();
};
img.src = url;
}
function printBarcode(svgId) {
const svg = document.getElementById(svgId);
if (!svg) return;
// Serialize the SVG
const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svg);
// Open a new window for printing
const printWindow = window.open('', '_blank');
printWindow.document.write(`
Print Barcode
${svgString}
`);
printWindow.document.close();
printWindow.focus();
printWindow.print();
printWindow.close();
}
function idToEAN13(id) {
const padded = id.toString().padStart(12, "0"); // 12 digits
return padded;
}
// Table filter
document.addEventListener('DOMContentLoaded', () => {
const filters = document.querySelectorAll('.column-filter');
const table = document.querySelector('table');
if (table == null) {
return;
}
const tbody = table.querySelector('tbody');
filters.forEach(filter => {
filter.addEventListener('input', () => {
const rows = tbody.querySelectorAll('tr');
const filterValues = Array.from(filters).map(f => f.value.toLowerCase().trim());
rows.forEach(row => {
const cells = row.querySelectorAll('td');
let visible = true;
filterValues.forEach((val, i) => {
if (val && !cells[i].textContent.toLowerCase().includes(val)) {
visible = false;
}
});
row.style.display = visible ? '' : 'none';
});
});
});
});
async function loadLocationsIntoSelect(selectElement, selectedValue = null) {
try {
const response = await fetch('/Locations/Index');
const locations = await response.json();
const ts = selectElement.tomselect;
if (!ts) {
selectElement.innerHTML = ``;
locations.forEach(loc => {
const option = document.createElement('option');
option.value = loc.location;
option.textContent = loc.location;
if (selectedValue && selectedValue === loc.location) {
option.selected = true;
}
selectElement.appendChild(option);
});
return;
}
ts.clearOptions();
ts.addOption(locations.map(loc => ({
value: loc.location,
text: loc.location
})));
ts.refreshOptions(false);
if (selectedValue) {
ts.setValue(selectedValue);
} else {
ts.clear(true);
}
} catch (err) {
console.error('Error loading locations:', err);
showToast(appTranslations.errorLoadingLocations, 'danger');
}
}
async function loadUsersIntoSelect(selectElement, selectedValue = null) {
try {
const response = await fetch('/Users/Index?Cn=false&Sn=false&Title=false&Description=false&JpegPhoto=false&UserPassword=false');
const users = await response.json();
const ts = selectElement.tomselect;
if (!ts) {
selectElement.innerHTML = ``;
users.forEach(u => {
const opt = document.createElement('option');
opt.value = u.uid;
opt.textContent = u.uid;
selectElement.appendChild(opt);
});
return;
}
ts.clearOptions();
ts.addOption(users.map(u => ({ value: u.uid, text: u.uid })));
ts.refreshOptions(false);
if (selectedValue) ts.setValue(selectedValue);
} catch (err) {
console.error('Error loading users:', err);
showToast(appTranslations.errorLoadingUsers, 'danger');
}
}
function validatePassword(password) {
// Regex: min 8 chars, one uppercase, one lowercase, one number, one special char
const strongPasswordRegex =
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_\-+=\[{\]};:'",<.>/?\\|`~]).{8,}$/;
return strongPasswordRegex.test(password);
}