Fix: Umfassendes Refactoring des Print-CSS und Filter-Logik
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 37s
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 37s
This commit is contained in:
@@ -85,7 +85,7 @@ $sql = "SELECT
|
||||
u.username as creator_name, a.household_id, a.product_designation,
|
||||
c.id AS category_id, c.name AS category_name, c.color AS category_color,
|
||||
m.id AS manufacturer_id, m.name AS manufacturer_name,
|
||||
a.storage_location_id, l2.name AS location_level2_name, l1.name AS location_level1_name
|
||||
a.storage_location_id, l2.parent_id AS loc_parent_id, l2.name AS location_level2_name, l1.name AS location_level1_name
|
||||
FROM articles a
|
||||
JOIN users u ON a.user_id = u.id
|
||||
LEFT JOIN categories c ON a.category_id = c.id
|
||||
@@ -412,11 +412,32 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
updateBulkUI();
|
||||
});
|
||||
|
||||
document.querySelectorAll('.sortable-header').forEach(header => {
|
||||
header.addEventListener('click', function() {
|
||||
const sort = this.getAttribute('data-sort');
|
||||
if (currentSortColumn === sort) {
|
||||
currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
currentSortColumn = sort;
|
||||
currentSortDirection = 'asc';
|
||||
}
|
||||
// Update icons
|
||||
document.querySelectorAll('.sortable-header i.fa-sort, .sortable-header i.fa-sort-up, .sortable-header i.fa-sort-down').forEach(icon => {
|
||||
icon.className = 'fas fa-sort text-muted ms-1';
|
||||
});
|
||||
const icon = this.querySelector('i');
|
||||
icon.className = currentSortDirection === 'asc' ? 'fas fa-sort-up text-primary ms-1' : 'fas fa-sort-down text-primary ms-1';
|
||||
|
||||
renderTable();
|
||||
});
|
||||
});
|
||||
|
||||
function renderTable() {
|
||||
const textValue = filterText.value.toLowerCase();
|
||||
const categoryValue = filterCategory.value;
|
||||
const manufacturerValue = filterManufacturer.value;
|
||||
const isSearching = textValue.length > 0 || categoryValue || manufacturerValue;
|
||||
const locationValue = filterLocation ? filterLocation.value : '';
|
||||
const isSearching = textValue.length > 0 || categoryValue || manufacturerValue || locationValue;
|
||||
|
||||
function articleMatchesFilter(article) {
|
||||
const matchesText = article.name.toLowerCase().includes(textValue) ||
|
||||
@@ -424,7 +445,10 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
(article.product_designation && article.product_designation.toLowerCase().includes(textValue));
|
||||
const matchesCategory = !categoryValue || article.category_id == categoryValue;
|
||||
const matchesManufacturer = !manufacturerValue || article.manufacturer_id == manufacturerValue;
|
||||
return matchesText && matchesCategory && matchesManufacturer;
|
||||
const locId = article.storage_location_id;
|
||||
const locParentId = article.loc_parent_id;
|
||||
const matchesLocation = !locationValue || locId == locationValue || locParentId == locationValue;
|
||||
return matchesText && matchesCategory && matchesManufacturer && matchesLocation;
|
||||
}
|
||||
|
||||
const filteredList = articlesHierarchical.filter(article => {
|
||||
@@ -460,12 +484,23 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
else cmp = a.localeCompare(b);
|
||||
return currentSortDirection === 'asc' ? cmp : -cmp;
|
||||
});
|
||||
// Sort items inside groups by name
|
||||
Object.keys(groupedArticles).forEach(key => {
|
||||
groupedArticles[key].sort((a, b) => a.name.localeCompare(b.name));
|
||||
});
|
||||
} else {
|
||||
groupedArticles['Suchergebnisse'] = [...filteredList];
|
||||
// Flatten the list for sorting all items (including children) independent of hierarchy
|
||||
const flatList = [];
|
||||
function flatten(list) {
|
||||
list.forEach(item => {
|
||||
flatList.push(item);
|
||||
if (item.children && item.children.length > 0) {
|
||||
flatten(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
flatten(filteredList);
|
||||
|
||||
groupedArticles['Suchergebnisse'] = flatList;
|
||||
groupedArticles['Suchergebnisse'].sort((a, b) => {
|
||||
let valA = a[currentSortColumn] || '';
|
||||
let valB = b[currentSortColumn] || '';
|
||||
@@ -515,9 +550,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
if (!isCollapsed) {
|
||||
items.forEach(article => {
|
||||
tableHTML += generateRowHTML(article);
|
||||
tableHTML += generateRowHTML(article, 0, isGrouped);
|
||||
gridHTML += generateCardHTML(article);
|
||||
if (article.children.length > 0) {
|
||||
if (isGrouped && article.children.length > 0) {
|
||||
article.children.forEach(child => {
|
||||
gridHTML += generateCardHTML(child);
|
||||
});
|
||||
@@ -764,4 +799,6 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'footer.php'; ?>/script>
|
||||
|
||||
<?php require_once 'footer.php'; ?>
|
||||
@@ -322,53 +322,86 @@ function showBarcode(token, name) {
|
||||
new bootstrap.Modal(document.getElementById('barcodeModal')).show();
|
||||
}
|
||||
|
||||
function showAllBarcodes(jsonStr, level1Name) {
|
||||
const data = JSON.parse(jsonStr);
|
||||
window.currentBarcodeData = [];
|
||||
window.currentBarcodeLevel1Name = '';
|
||||
|
||||
window.showAllBarcodes = function(jsonStr, level1Name) {
|
||||
window.currentBarcodeData = JSON.parse(jsonStr);
|
||||
window.currentBarcodeLevel1Name = level1Name;
|
||||
document.getElementById('printModalLabel').textContent = "QR-Codes für: " + level1Name;
|
||||
window.renderAllBarcodes();
|
||||
new bootstrap.Modal(document.getElementById('printModal')).show();
|
||||
}
|
||||
|
||||
window.renderAllBarcodes = function() {
|
||||
const container = document.getElementById('allBarcodesContainer');
|
||||
container.innerHTML = '';
|
||||
const baseUrl = window.location.origin + window.location.pathname.replace('storage_locations.php', 'public_location.php?token=');
|
||||
|
||||
document.getElementById('printModalLabel').textContent = "QR-Codes für: " + level1Name;
|
||||
const sizeMM = document.getElementById('qrSizeInput') ? document.getElementById('qrSizeInput').value : 40;
|
||||
|
||||
data.forEach(item => {
|
||||
window.currentBarcodeData.forEach(item => {
|
||||
const url = baseUrl + item.token;
|
||||
const col = document.createElement('div');
|
||||
col.className = 'col-6 col-md-4 mb-4 text-center';
|
||||
col.className = 'print-item text-center';
|
||||
col.style.cssText = 'margin: 10px; page-break-inside: avoid; display: inline-block; width: ' + (parseInt(sizeMM) + 20) + 'mm;';
|
||||
col.innerHTML = `
|
||||
<div class="border p-3 bg-white" style="page-break-inside: avoid;">
|
||||
<div class="bg-white">
|
||||
<p class="fw-bold mb-2 text-truncate" style="font-size: 0.9rem;">${item.name}</p>
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${encodeURIComponent(url)}" alt="QR Code" class="img-fluid mb-2">
|
||||
<img src="https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent(url)}" alt="QR Code" style="border: 1px solid #000; padding: 1mm; width: ${sizeMM}mm; height: ${sizeMM}mm; box-sizing: border-box;" class="mb-2">
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(col);
|
||||
});
|
||||
|
||||
new bootstrap.Modal(document.getElementById('printModal')).show();
|
||||
}
|
||||
|
||||
function printDiv(divId) {
|
||||
var printContents = document.getElementById(divId).innerHTML;
|
||||
var originalContents = document.body.innerHTML;
|
||||
document.body.innerHTML = `
|
||||
<style>
|
||||
body { font-family: sans-serif; background: none !important; background-color: white !important; }
|
||||
.print-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; }
|
||||
.print-item { text-align: center; margin-bottom: 20px; page-break-inside: avoid; }
|
||||
p { margin: 0 0 5px 0; font-size: 14px; font-weight: bold; color: black !important; }
|
||||
img { display: inline-block !important; }
|
||||
</style>
|
||||
<div class="print-grid">${printContents}</div>
|
||||
`;
|
||||
|
||||
// Wait a brief moment to ensure QR code images from the external API are fully loaded before triggering print
|
||||
setTimeout(function() {
|
||||
window.print();
|
||||
document.body.innerHTML = originalContents;
|
||||
window.location.reload(); // Reload to restore event listeners after print
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@media print {
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
body {
|
||||
background: none !important;
|
||||
background-color: white !important;
|
||||
}
|
||||
#printModal, #printModal * {
|
||||
visibility: visible;
|
||||
}
|
||||
#printModal {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.modal-header, .modal-footer, .d-print-none {
|
||||
display: none !important;
|
||||
}
|
||||
#allBarcodesContainer {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
justify-content: flex-start !important;
|
||||
gap: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.print-item {
|
||||
display: inline-block !important;
|
||||
}
|
||||
.modal-dialog {
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.modal-content {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.modal-backdrop {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="modal fade" id="printModal" tabindex="-1" aria-labelledby="printModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
@@ -385,7 +418,7 @@ function printDiv(divId) {
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
||||
<button type="button" class="btn btn-primary" onclick="printDiv('allBarcodesContainer')"><i class="fas fa-print me-2"></i>Jetzt drucken</button>
|
||||
<button type="button" class="btn btn-primary" onclick="window.print()"><i class="fas fa-print me-2"></i>Jetzt drucken</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user