function init() { const gridContainer = document.querySelector('.grid-container'); if (!gridContainer) return; // Werte aus den data-Attributen holen oder Standardwerte setzen const gridRows = parseInt(gridContainer.dataset.rows) || 1; // Standardwert für Reihen: 5 const gridCols = parseInt(gridContainer.dataset.cols) || 6; // Standardwert für Spalten: 5 let selectedIndices = []; // Grid erstellen const fragment = document.createDocumentFragment(); // Erstelle die Zellen basierend auf Reihen und Spalten (gridRows * gridCols) for (let i = 0; i < gridRows * gridCols; i++) { const gridItem = document.createElement('div'); gridItem.classList.add('grid-cell'); gridItem.dataset.index = i; // Weise jeder Zelle ihren Index zu gridItem.addEventListener('click', () => toggleCell(i)); // Event für Klick hinzufügen fragment.appendChild(gridItem); } gridContainer.appendChild(fragment); /** * Zelle ein-/auswählen * @param {number} index - Der Index der Zelle */ function toggleCell(index) { if (selectedIndices.includes(index)) { // Zelle abwählen removeRowOrColumn(index); } else { // Zelle hinzufügen selectedIndices.push(index); fillSelection(); // Rechteck auffüllen } updateGrid(); // Visuelle Aktualisierung saveSelection(); // Speicherung der Auswahl } /** * Entfernt eine Zeile oder eine Spalte basierend auf dem Index * @param {number} index - Der Index der Zelle */ function removeRowOrColumn(index) { const row = Math.floor(index / gridCols); // Berechnet die aktuelle Reihe const col = index % gridCols; // Berechnet die aktuelle Spalte if (col === 0) { // Entferne die gesamte Reihe, wenn das Feld in der ersten Spalte ist // UND entferne alle darunterliegenden Reihen selectedIndices = selectedIndices.filter(cell => { const cellRow = Math.floor(cell / gridCols); return cellRow < row; // Entferne alle Reihen >= der aktuellen }); } else { // Entferne die gesamte Spalte, wenn das Feld NICHT in der ersten Spalte ist selectedIndices = selectedIndices.filter(cell => { const cellCol = cell % gridCols; return cellCol !== col; }); // Prüfe, ob Spalten rechts entfernt werden müssen, um Lücken zu vermeiden adjustRectangleAfterColumnRemoval(); } } /** * Passt das Rechteck an, indem leere Spalten rechts entfernt werden */ function adjustRectangleAfterColumnRemoval() { if (selectedIndices.length === 0) return; // Ermittle die minimalen und maximalen Spalten des bestehenden Rechtecks const firstCol = Math.min(...selectedIndices.map(cell => cell % gridCols)); const lastCol = Math.max(...selectedIndices.map(cell => cell % gridCols)); // Prüfe jede Spalte von links nach rechts for (let col = firstCol; col <= lastCol; col++) { // Überprüfen, ob diese Spalte komplett leer ist const isColumnEmpty = !selectedIndices.some(cell => cell % gridCols === col); if (isColumnEmpty) { // Entferne alle Zellen in Spalten rechts von der leeren Spalte selectedIndices = selectedIndices.filter(cell => cell % gridCols < col); break; // Stoppe, wenn wir eine leere Spalte finden } } } /** * Füllt die Auswahl als Rechteck aus */ function fillSelection() { if (selectedIndices.length === 0) return; // Ermittle die minimalen und maximalen Indizes const firstRow = Math.min(...selectedIndices.map(cell => Math.floor(cell / gridCols))); const lastRow = Math.max(...selectedIndices.map(cell => Math.floor(cell / gridCols))); const firstCol = Math.min(...selectedIndices.map(cell => cell % gridCols)); const lastCol = Math.max(...selectedIndices.map(cell => cell % gridCols)); // Rechteck auffüllen: Alle Zellen zwischen den Ecken hinzufügen const newSelection = []; for (let row = firstRow; row <= lastRow; row++) { for (let col = firstCol; col <= lastCol; col++) { const cellIndex = row * gridCols + col; newSelection.push(cellIndex); } } selectedIndices = newSelection; // Aktualisiere die Auswahl } /** * Aktualisiert die visuelle Darstellung des Grids */ function updateGrid() { // Entferne die "selected"-Klasse von allen Zellen gridContainer.querySelectorAll('.grid-cell').forEach(cell => { cell.classList.remove('selected'); }); // Füge die "selected"-Klasse zu den ausgewählten Zellen hinzu selectedIndices.forEach(index => { gridContainer .querySelector(`.grid-cell[data-index="${index}"]`) ?.classList.add('selected'); }); } /** * Speichert die Auswahl in einem versteckten Eingabeelement */ function saveSelection() { const gridDataInput = document.getElementById('ctrl_vr_gpw_grid'); if (gridDataInput) { gridDataInput.value = JSON.stringify(selectedIndices); } } } document.addEventListener('DOMContentLoaded', () => {init()}); document.addEventListener('turbo:render', () => {init()});