Feature: Editierbare ToDo-Listen, Artikel-Kachelansicht, gefilterter Export und Haushalts-Namen Fix
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 38s
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 38s
This commit is contained in:
@@ -206,4 +206,7 @@ Das Projekt basiert auf bewährten Web-Standards:
|
||||
* JavaScript-Standardmeldungen (`confirm()`) für das Löschen von Artikeln in Phase 1 durch moderne Bootstrap-Modals ersetzt.
|
||||
* Styling der aktiven ToDo-Liste verbessert (grüner Hintergrund statt schwarzem Rand).
|
||||
* Fatal Error auf der Hilfe-Seite (`help.php`) beim Aufruf ohne bestehende DB-Verbindung behoben.
|
||||
* CSV-Export Funktion für alle Artikel im Bestand hinzugefügt.
|
||||
* CSV-Export Funktion für alle Artikel im Bestand hinzugefügt (mit Abfrage, ob alle oder nur aktuell gefilterte exportiert werden sollen).
|
||||
* Neue Kachelansicht für die Artikel-Übersicht inklusive Toggle-Button zwischen Listen- und Kachelansicht.
|
||||
* Bearbeiten-Funktion für bestehende ToDo-Listen Titel und deren Einträge implementiert.
|
||||
* Anzeige in der Haushaltsverwaltung nutzt nun den Anzeigenamen (Display Name) anstatt des Loginnamens, sofern vorhanden.
|
||||
|
||||
118
src/articles.php
118
src/articles.php
@@ -128,7 +128,7 @@ $conn->close();
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h2 class="h4 mb-0"><i class="fas fa-boxes me-2"></i>Artikel im Haushalt</h2>
|
||||
<div>
|
||||
<a href="export_articles.php" class="btn btn-sm btn-outline-success me-2"><i class="fas fa-file-export me-2"></i>Export (CSV)</a>
|
||||
<button type="button" class="btn btn-sm btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#exportModal"><i class="fas fa-file-export me-2"></i>Export (CSV)</button>
|
||||
<a href="add_article.php" class="btn btn-sm btn-outline-light"><i class="fas fa-plus me-2"></i>Neuen Artikel hinzufügen</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -141,6 +141,10 @@ $conn->close();
|
||||
<div class="col-md-3"><select id="filter-category" class="form-select form-select-sm"><option value="">Alle Kategorien</option><?php foreach($categories_for_filter as $cat) echo '<option value="'.$cat['id'].'">'.htmlspecialchars($cat['name']).'</option>'; ?></select></div>
|
||||
<div class="col-md-3"><select id="filter-manufacturer" class="form-select form-select-sm"><option value="">Alle Hersteller</option><?php foreach($manufacturers_for_filter as $man) echo '<option value="'.$man['id'].'">'.htmlspecialchars($man['name']).'</option>'; ?></select></div>
|
||||
<div class="col-md-2 text-end">
|
||||
<div class="btn-group btn-group-sm me-2" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary active" id="btn-view-list" title="Listenansicht"><i class="fas fa-list"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary" id="btn-view-grid" title="Kachelansicht"><i class="fas fa-th"></i></button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary" id="btn-expand-all" title="Alle ausklappen"><i class="fas fa-expand-alt"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary" id="btn-collapse-all" title="Alle einklappen"><i class="fas fa-compress-alt"></i></button>
|
||||
@@ -149,7 +153,7 @@ $conn->close();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive" style="max-height: 75vh;">
|
||||
<div id="view-container-list" class="table-responsive" style="max-height: 75vh;">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -171,9 +175,34 @@ $conn->close();
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="view-container-grid" class="p-3" style="max-height: 75vh; overflow-y: auto; display: none;">
|
||||
<div class="row g-3" id="articlesGridBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="exportModal" tabindex="-1" aria-labelledby="exportModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exportModalLabel">Artikel exportieren</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Möchten Sie alle Artikel im Haushalt exportieren oder nur die aktuell gefilterten Ergebnisse?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<form action="export_articles.php" method="POST" id="exportForm" class="m-0">
|
||||
<input type="hidden" name="export_ids" id="export_ids_input" value="">
|
||||
<button type="submit" name="export_type" value="all" class="btn btn-outline-secondary" onclick="document.getElementById('exportModal').querySelector('.btn-close').click();">Alle Artikel</button>
|
||||
<button type="submit" name="export_type" value="filtered" class="btn btn-success" onclick="document.getElementById('exportModal').querySelector('.btn-close').click();">Nur Gefilterte</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="imageModal" tabindex="-1" aria-labelledby="imageModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
@@ -216,6 +245,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const filterManufacturer = document.getElementById('filter-manufacturer');
|
||||
|
||||
const collapsedCategories = new Set();
|
||||
let currentView = 'list';
|
||||
|
||||
// Initialize collapsed state based on user setting
|
||||
if (collapseDefault) {
|
||||
@@ -226,6 +256,23 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
uniqueCategories.forEach(c => collapsedCategories.add(c));
|
||||
}
|
||||
|
||||
document.getElementById('btn-view-list').addEventListener('click', function() {
|
||||
currentView = 'list';
|
||||
this.classList.add('active');
|
||||
document.getElementById('btn-view-grid').classList.remove('active');
|
||||
document.getElementById('view-container-list').style.display = '';
|
||||
document.getElementById('view-container-grid').style.display = 'none';
|
||||
renderTable();
|
||||
});
|
||||
document.getElementById('btn-view-grid').addEventListener('click', function() {
|
||||
currentView = 'grid';
|
||||
this.classList.add('active');
|
||||
document.getElementById('btn-view-list').classList.remove('active');
|
||||
document.getElementById('view-container-list').style.display = 'none';
|
||||
document.getElementById('view-container-grid').style.display = '';
|
||||
renderTable();
|
||||
});
|
||||
|
||||
function renderTable() {
|
||||
const textValue = filterText.value.toLowerCase();
|
||||
const categoryValue = filterCategory.value;
|
||||
@@ -247,6 +294,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
return false;
|
||||
});
|
||||
|
||||
// Update Export Modal
|
||||
const exportIds = filteredList.flatMap(a => {
|
||||
const ids = [a.id];
|
||||
if (a.children) {
|
||||
a.children.forEach(c => ids.push(c.id));
|
||||
}
|
||||
return ids;
|
||||
});
|
||||
document.getElementById('export_ids_input').value = exportIds.join(',');
|
||||
|
||||
const groupedArticles = {};
|
||||
filteredList.forEach(article => {
|
||||
const catName = article.category_name || 'Ohne Kategorie';
|
||||
@@ -261,9 +318,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
|
||||
let tableHTML = '';
|
||||
let gridHTML = '';
|
||||
|
||||
if (sortedCategories.length === 0) {
|
||||
tableHTML = '<tr><td colspan="12" class="text-center text-muted p-4">Keine Artikel gefunden.</td></tr>';
|
||||
gridHTML = '<div class="col-12 text-center text-muted p-4">Keine Artikel gefunden.</div>';
|
||||
} else {
|
||||
sortedCategories.forEach(catName => {
|
||||
const items = groupedArticles[catName];
|
||||
@@ -281,15 +340,70 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (!isCollapsed) {
|
||||
items.forEach(article => {
|
||||
tableHTML += generateRowHTML(article);
|
||||
gridHTML += generateCardHTML(article);
|
||||
if (article.children.length > 0) {
|
||||
article.children.forEach(child => {
|
||||
gridHTML += generateCardHTML(child);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tableBody.innerHTML = tableHTML;
|
||||
document.getElementById('articlesGridBody').innerHTML = gridHTML;
|
||||
initializeInteractivity();
|
||||
}
|
||||
|
||||
function generateCardHTML(article) {
|
||||
const imagePath = article.image_url ? article.image_url : 'assets/images/keinbild.png';
|
||||
const productLink = article.product_url ? `<a href="${article.product_url}" target="_blank" class="btn btn-sm btn-outline-secondary" data-bs-toggle="tooltip" title="Produktseite öffnen"><i class="fas fa-external-link-alt"></i></a>` : '';
|
||||
const householdBadge = article.household_id ? `<span class="badge bg-success" data-bs-toggle="tooltip" title="Für den Haushalt freigegeben"><i class="fas fa-users"></i></span>` : `<span class="badge bg-secondary" data-bs-toggle="tooltip" title="Privater Artikel"><i class="fas fa-user"></i></span>`;
|
||||
const consumableIcon = article.consumable == 1 ? ` <i class="fas fa-cookie-bite text-warning" data-bs-toggle="tooltip" title="Verbrauchsartikel"></i>` : '';
|
||||
const quantityBadge = article.consumable == 1 ? `<span class="badge bg-secondary rounded-pill" data-bs-toggle="tooltip" title="Verbrauchsartikel">∞</span>` : `<span class="badge bg-secondary rounded-pill">${article.quantity_owned} x</span>`;
|
||||
|
||||
let actionButtons = '';
|
||||
const isOwner = (article.user_id == currentUserId);
|
||||
const isHouseholdArticle = (article.household_id && article.household_id == currentUserHouseholdId);
|
||||
|
||||
if (isOwner || isHouseholdArticle) {
|
||||
actionButtons = `<div class="btn-group">
|
||||
<a href="edit_article.php?id=${article.id}" class="btn btn-sm btn-outline-primary" data-bs-toggle="tooltip" title="Bearbeiten"><i class="fas fa-edit"></i></a>`;
|
||||
actionButtons += `<form action="articles.php" method="post" class="d-inline" onsubmit="return confirm('Sind Sie sicher?');"><input type="hidden" name="delete_article_id" value="${article.id}"><button type="submit" class="btn btn-sm btn-outline-danger" data-bs-toggle="tooltip" title="Löschen"><i class="fas fa-trash"></i></button></form>`;
|
||||
actionButtons += `</div>`;
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card h-100 shadow-sm position-relative border-0 article-card">
|
||||
<img src="${imagePath}" class="card-img-top article-image-trigger" data-preview-url="${imagePath}" alt="${article.name}" style="height: 180px; object-fit: cover; cursor: pointer; border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;">
|
||||
<div class="position-absolute top-0 end-0 p-2">
|
||||
${householdBadge} ${consumableIcon}
|
||||
</div>
|
||||
<div class="card-body d-flex flex-column p-3">
|
||||
<h5 class="card-title text-truncate mb-2" title="${article.name}">${article.name}</h5>
|
||||
<div class="mb-2">
|
||||
<span class="badge bg-light text-dark border"><i class="fas fa-weight-hanging me-1"></i> ${new Intl.NumberFormat('de-DE').format(article.weight_grams)} g</span>
|
||||
${quantityBadge}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<span class="badge bg-info text-dark border">${article.category_name || 'Ohne Kat.'}</span>
|
||||
</div>
|
||||
<p class="card-text small text-muted mb-1 mt-auto" style="line-height: 1.2;">
|
||||
${article.manufacturer_name ? `<strong>Hersteller:</strong> ${article.manufacturer_name}<br>` : ''}
|
||||
${article.product_designation ? `<strong>Modell:</strong> ${article.product_designation}` : ''}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-footer bg-light border-top d-flex justify-content-between align-items-center p-2">
|
||||
${productLink}
|
||||
${actionButtons}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function generateRowHTML(article, level = 0) {
|
||||
let html = '';
|
||||
const imagePath = article.image_url ? article.image_url : 'assets/images/keinbild.png';
|
||||
|
||||
@@ -37,6 +37,21 @@ if ($current_user_household_id) {
|
||||
$placeholders = implode(',', array_fill(0, count($household_member_ids), '?'));
|
||||
$types = str_repeat('i', count($household_member_ids));
|
||||
|
||||
$where_clause = "(a.user_id IN ($placeholders) OR a.household_id = ?)";
|
||||
$all_params = array_merge($household_member_ids, [$current_user_household_id]);
|
||||
$all_types = $types . 'i';
|
||||
|
||||
if (isset($_POST['export_type']) && $_POST['export_type'] == 'filtered' && !empty($_POST['export_ids'])) {
|
||||
$ids = explode(',', $_POST['export_ids']);
|
||||
$valid_ids = array_map('intval', $ids);
|
||||
if (count($valid_ids) > 0) {
|
||||
$id_placeholders = implode(',', array_fill(0, count($valid_ids), '?'));
|
||||
$where_clause .= " AND a.id IN ($id_placeholders)";
|
||||
$all_params = array_merge($all_params, $valid_ids);
|
||||
$all_types .= str_repeat('i', count($valid_ids));
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
a.name AS 'Artikelname',
|
||||
a.product_designation AS 'Produktbezeichnung',
|
||||
@@ -55,7 +70,7 @@ $sql = "SELECT
|
||||
LEFT JOIN manufacturers m ON a.manufacturer_id = m.id
|
||||
LEFT JOIN storage_locations l2 ON a.storage_location_id = l2.id
|
||||
LEFT JOIN storage_locations l1 ON l2.parent_id = l1.id
|
||||
WHERE a.user_id IN ($placeholders) OR a.household_id = ?
|
||||
WHERE $where_clause
|
||||
ORDER BY c.name ASC, a.name ASC";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
@@ -63,8 +78,6 @@ if ($stmt === false) {
|
||||
die("Datenbankfehler.");
|
||||
}
|
||||
|
||||
$all_params = array_merge($household_member_ids, [$current_user_household_id]);
|
||||
$all_types = $types . 'i';
|
||||
$stmt->bind_param($all_types, ...$all_params);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
@@ -46,12 +46,12 @@ if ($household_id) {
|
||||
// Mitglieder und deren Statistiken laden
|
||||
$stmt_members = $conn->prepare("
|
||||
SELECT
|
||||
u.id, u.username,
|
||||
u.id, COALESCE(NULLIF(u.display_name, ''), u.username) AS username,
|
||||
(SELECT COUNT(*) FROM articles WHERE user_id = u.id) as article_count,
|
||||
(SELECT COUNT(*) FROM packing_lists WHERE user_id = u.id) as list_count
|
||||
FROM users u
|
||||
WHERE u.household_id = ?
|
||||
ORDER BY u.username
|
||||
ORDER BY username
|
||||
");
|
||||
$stmt_members->bind_param("i", $household_id);
|
||||
$stmt_members->execute();
|
||||
@@ -59,7 +59,7 @@ if ($household_id) {
|
||||
$stmt_members->close();
|
||||
|
||||
// Eingeladene Mitglieder laden
|
||||
$stmt_pending = $conn->prepare("SELECT u.username FROM household_invitations hi JOIN users u ON hi.invited_user_id = u.id WHERE hi.household_id = ? AND hi.status = 'pending'");
|
||||
$stmt_pending = $conn->prepare("SELECT COALESCE(NULLIF(u.display_name, ''), u.username) AS username FROM household_invitations hi JOIN users u ON hi.invited_user_id = u.id WHERE hi.household_id = ? AND hi.status = 'pending'");
|
||||
$stmt_pending->bind_param("i", $household_id);
|
||||
$stmt_pending->execute();
|
||||
$pending_invitations = $stmt_pending->get_result()->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
@@ -58,6 +58,24 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
$stmt->bind_param("i", $item_id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
} elseif (isset($_POST['edit_list'])) {
|
||||
$list_id = intval($_POST['list_id']);
|
||||
$name = trim($_POST['list_name']);
|
||||
if (!empty($name)) {
|
||||
$stmt = $conn->prepare("UPDATE todo_lists SET name = ? WHERE id = ? AND (user_id = ? OR household_id = ?)");
|
||||
$stmt->bind_param("siii", $name, $list_id, $current_user_id, $current_user_household_id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
} elseif (isset($_POST['edit_item'])) {
|
||||
$item_id = intval($_POST['item_id']);
|
||||
$title = trim($_POST['item_title']);
|
||||
if (!empty($title)) {
|
||||
$stmt = $conn->prepare("UPDATE todo_items SET title = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $title, $item_id);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
} elseif (isset($_POST['toggle_item'])) {
|
||||
$item_id = intval($_POST['item_id']);
|
||||
$status = isset($_POST['status']) ? intval($_POST['status']) : 0;
|
||||
@@ -131,28 +149,57 @@ $active_list_id = isset($_GET['list_id']) ? intval($_GET['list_id']) : (!empty($
|
||||
foreach ($todo_lists as $l) if ($l['id'] == $active_list_id) $active_list_name = $l['name'];
|
||||
?>
|
||||
<div class="card h-100 border-0 shadow-sm">
|
||||
<div class="card-header bg-white border-bottom">
|
||||
<h5 class="mb-0 py-2"><i class="fas fa-tasks me-2 text-muted"></i><?php echo htmlspecialchars($active_list_name); ?></h5>
|
||||
<div class="card-header bg-white border-bottom" id="list-title-container-<?php echo $active_list_id; ?>">
|
||||
<h5 class="mb-0 py-2 d-flex justify-content-between align-items-center w-100">
|
||||
<span><i class="fas fa-tasks me-2 text-muted"></i><span id="list-name-text-<?php echo $active_list_id; ?>"><?php echo htmlspecialchars($active_list_name); ?></span></span>
|
||||
<button class="btn btn-sm btn-link text-secondary" onclick="editListTitle(<?php echo $active_list_id; ?>)"><i class="fas fa-edit"></i></button>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-header bg-white border-bottom" id="edit-list-form-container-<?php echo $active_list_id; ?>" style="display:none;">
|
||||
<form method="post" id="edit-list-form-<?php echo $active_list_id; ?>" class="w-100 py-1 m-0">
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<input type="text" name="list_name" class="form-control" id="edit-list-input-<?php echo $active_list_id; ?>" value="<?php echo htmlspecialchars($active_list_name); ?>">
|
||||
<button type="submit" name="edit_list" class="btn btn-success"><i class="fas fa-check"></i></button>
|
||||
<button type="button" class="btn btn-secondary" onclick="cancelEditListTitle(<?php echo $active_list_id; ?>)"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<ul class="list-group shadow-sm mb-4">
|
||||
<?php foreach ($items as $item): ?>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center py-3 px-2 border-bottom">
|
||||
<form method="post" style="display:inline; margin:0;" class="flex-grow-1">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item['id']; ?>">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<div class="form-check d-flex align-items-center mb-0">
|
||||
<input class="form-check-input me-3" type="checkbox" onChange="this.form.submit()" name="status" value="<?php echo $item['is_completed'] ? '0' : '1'; ?>" <?php echo $item['is_completed'] ? 'checked' : ''; ?> style="width:1.5em; height:1.5em; cursor:pointer;">
|
||||
<input type="hidden" name="toggle_item" value="1">
|
||||
<label class="form-check-label <?php echo $item['is_completed'] ? 'text-decoration-line-through text-muted' : ''; ?>" style="cursor:pointer; font-size:1.1em; width:100%; margin-top:2px;">
|
||||
<?php echo htmlspecialchars($item['title']); ?>
|
||||
</label>
|
||||
<li class="list-group-item py-3 px-2 border-bottom" id="item-container-<?php echo $item['id']; ?>">
|
||||
<div class="d-flex justify-content-between align-items-center w-100">
|
||||
<form method="post" style="display:inline; margin:0;" class="flex-grow-1">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item['id']; ?>">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<div class="form-check d-flex align-items-center mb-0">
|
||||
<input class="form-check-input me-3" type="checkbox" onChange="this.form.submit()" name="status" value="<?php echo $item['is_completed'] ? '0' : '1'; ?>" <?php echo $item['is_completed'] ? 'checked' : ''; ?> style="width:1.5em; height:1.5em; cursor:pointer;">
|
||||
<input type="hidden" name="toggle_item" value="1">
|
||||
<label class="form-check-label <?php echo $item['is_completed'] ? 'text-decoration-line-through text-muted' : ''; ?>" style="cursor:pointer; font-size:1.1em; width:100%; margin-top:2px;">
|
||||
<?php echo htmlspecialchars($item['title']); ?>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-link text-secondary" onclick="editItemTitle(<?php echo $item['id']; ?>)"><i class="fas fa-edit"></i></button>
|
||||
<form method="post" style="display:inline;" onsubmit="return confirm('Eintrag wirklich löschen?');">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item['id']; ?>">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<button type="submit" name="delete_item" class="btn btn-sm btn-link text-danger p-0 ms-2" title="Punkt entfernen"><i class="fas fa-times"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="list-group-item py-3 px-2 border-bottom" id="edit-item-container-<?php echo $item['id']; ?>" style="display:none;">
|
||||
<form method="post" class="w-100 m-0">
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item['id']; ?>">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<input type="text" name="item_title" class="form-control" id="edit-item-input-<?php echo $item['id']; ?>" value="<?php echo htmlspecialchars($item['title']); ?>">
|
||||
<button type="submit" name="edit_item" class="btn btn-success"><i class="fas fa-check"></i></button>
|
||||
<button type="button" class="btn btn-secondary" onclick="cancelEditItemTitle(<?php echo $item['id']; ?>)"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
<form method="post" style="display:inline;" class="ms-3">
|
||||
<input type="hidden" name="item_id" value="<?php echo $item['id']; ?>">
|
||||
<input type="hidden" name="list_id" value="<?php echo $active_list_id; ?>">
|
||||
<button type="submit" name="delete_item" class="btn btn-sm btn-outline-danger" title="Punkt entfernen"><i class="fas fa-times"></i></button>
|
||||
</form>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
@@ -183,6 +230,28 @@ $active_list_id = isset($_GET['list_id']) ? intval($_GET['list_id']) : (!empty($
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function editListTitle(id) {
|
||||
document.getElementById('list-title-container-' + id).style.display = 'none';
|
||||
document.getElementById('edit-list-form-container-' + id).style.display = 'block';
|
||||
document.getElementById('edit-list-input-' + id).focus();
|
||||
}
|
||||
function cancelEditListTitle(id) {
|
||||
document.getElementById('edit-list-form-container-' + id).style.display = 'none';
|
||||
document.getElementById('list-title-container-' + id).style.display = 'block'; // Or flex, depending on original
|
||||
document.getElementById('list-title-container-' + id).classList.add('d-flex');
|
||||
}
|
||||
function editItemTitle(id) {
|
||||
document.getElementById('item-container-' + id).style.display = 'none';
|
||||
document.getElementById('edit-item-container-' + id).style.display = 'block';
|
||||
document.getElementById('edit-item-input-' + id).focus();
|
||||
}
|
||||
function cancelEditItemTitle(id) {
|
||||
document.getElementById('edit-item-container-' + id).style.display = 'none';
|
||||
document.getElementById('item-container-' + id).style.display = 'block';
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
require_once 'footer.php';
|
||||
if (isset($conn) && $conn instanceof mysqli) {
|
||||
|
||||
Reference in New Issue
Block a user