Merge pull request #216 from LD-Reborn/191-feature-add-drag-and-drop-functionality-to-print-preview

191 feature add drag and drop functionality to print preview
This commit is contained in:
LD50
2025-11-01 13:15:43 +01:00
committed by GitHub

View File

@@ -83,7 +83,7 @@
} else {
assetCard.innerHTML = `
<div class="card-body">
<h6 class="card-title"><strong>Asset ${i}:</strong> @T["Empty"]</h6>
<h6 class="card-title"><strong>Asset ${i + 1}:</strong> @T["Empty"]</h6>
<div class="row">
<div id="printPreviewBatchButtons${i}" class="col-md-1 justify-content-end" style="margin-left: auto; width: auto;">
</div>
@@ -148,6 +148,7 @@
modalBody.appendChild(errorDiv);
}
}
enableDragAndDrop();
});
async function renderBarcodePreview(containerId = "printPreviewContainer") {
@@ -174,6 +175,7 @@
const cell = document.createElement("div");
cell.className = "barcode-cell border rounded p-1 d-flex flex-column align-items-center justify-content-center";
cell.style.minHeight = "120px";
cell.setAttribute("data-id", i);
var isMobileM = window.innerWidth < 992 && window.innerWidth >= 576;
var isMobileS = window.innerWidth < 576;
@@ -216,15 +218,20 @@
grid.appendChild(cell);
}
}
enableBarcodeDragAndDrop();
}
function moveCardInBatch(index, direction) {
const newIndex = direction === 'up' ? index - 1 : index - 0 + 1;
swapCardsInBatch(index, newIndex);
}
function swapCardsInBatch(index, newIndex) {
let batch = getAssetIdsFromBatch();
padNulls(batch, 24);
if (!batch || batch.length === 0) return;
const newIndex = direction === 'up' ? index - 1 : index - 0 + 1;
// Prevent out-of-bounds movement
if (newIndex < 0 || newIndex >= batch.length) return;
@@ -244,7 +251,131 @@
localStorage.setItem("printBatch", JSON.stringify(batch));
renderBarcodePreview();
}
function enableDragAndDrop() {
const cards = document.querySelectorAll('#printModal .card');
const modalBody = document.querySelector('#printModal .modal-body');
let draggedCard = null;
cards.forEach(card => {
card.setAttribute('draggable', 'true');
card.addEventListener('dragstart', e => {
draggedCard = card;
e.dataTransfer.effectAllowed = 'move';
e.target.style.opacity = '0.5';
});
card.addEventListener('dragend', e => {
e.target.style.opacity = '1';
draggedCard = null;
updateBatchOrderFromDOM();
});
card.addEventListener('dragover', e => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
const bounding = card.getBoundingClientRect();
const offset = bounding.y + (bounding.height / 2);
if (e.clientY - offset > 0) {
card.style['border-bottom'] = '2px solid #007bff';
card.style['border-top'] = '';
} else {
card.style['border-top'] = '2px solid #007bff';
card.style['border-bottom'] = '';
}
});
card.addEventListener('dragleave', e => {
card.style['border-bottom'] = '';
card.style['border-top'] = '';
});
card.addEventListener('drop', e => {
e.preventDefault();
card.style['border-bottom'] = '';
card.style['border-top'] = '';
const bounding = card.getBoundingClientRect();
const offset = bounding.y + (bounding.height / 2);
if (e.clientY - offset > 0) {
card.after(draggedCard);
} else {
card.before(draggedCard);
}
updateBatchOrderFromDOM();
});
});
}
function updateBatchOrderFromDOM() {
const newOrder = [];
const cards = document.querySelectorAll('#printModal .card');
cards.forEach((card, index) => {
// Update index attribute
card.setAttribute('data-card-index', index);
// Update the title text
const title = card.querySelector('.card-title strong');
if (title) title.textContent = `Asset ${index + 1}:`;
// Get asset CN if available
const assetCn = card.querySelector('.card-body')?.getAttribute('data-cn');
newOrder.push(assetCn || null);
});
localStorage.setItem("printBatch", JSON.stringify(newOrder));
renderBarcodePreview("printPreviewContainer");
}
function enableBarcodeDragAndDrop() {
const cells = document.querySelectorAll('#printPreviewContainer .barcode-cell');
const container = document.querySelector('#printPreviewContainer .barcode-grid');
let draggedCell = null;
cells.forEach(cell => {
cell.setAttribute('draggable', 'true');
cell.addEventListener('dragstart', e => {
draggedCell = cell;
e.dataTransfer.effectAllowed = 'move';
cell.style.opacity = '0.5';
});
cell.addEventListener('dragend', e => {
cell.style.opacity = '1';
draggedCell = null;
});
cell.addEventListener('dragover', e => {
e.preventDefault();
const bounding = cell.getBoundingClientRect();
const offset = bounding.y + bounding.height / 2;
if (e.clientY - offset > 0) {
cell.style['border-bottom'] = '2px solid #007bff';
cell.style['border-top'] = '';
} else {
cell.style['border-top'] = '2px solid #007bff';
cell.style['border-bottom'] = '';
}
});
cell.addEventListener('dragleave', e => {
cell.style['border-bottom'] = '';
cell.style['border-top'] = '';
});
cell.addEventListener('drop', e => {
e.preventDefault();
cell.style['border-bottom'] = '';
cell.style['border-top'] = '';
cell.after(draggedCell);
let index = cell.getAttribute("data-id");
let newIndex = draggedCell.getAttribute("data-id");
swapCardsInBatch(index, newIndex);
});
});
}
function getAssetIdsFromBatch() {
let currentData = JSON.parse(localStorage.getItem("printBatch"));
@@ -359,10 +490,16 @@
</head>
<body>
<div id="barcodeGrid" class="barcode-grid"></div>
<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/dist/JsBarcode.all.min.js"><\/script>
<script id="jsbarcodeScript" src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.6/dist/JsBarcode.all.min.js"><\/script>
</body>
</html>
`);
const waitForJsBarcode = new Promise(resolve => {
const script = printWindow.document.getElementById("jsbarcodeScript");
script.onload = () => resolve();
});
await waitForJsBarcode;
const grid = printWindow.document.getElementById("barcodeGrid");
for (let i = 0; i < batch.length; i++) {