Fix: TomSelect Dropdown-Anzeige (Z-Index, Images) in Rucksack-Bearbeitung
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 16s
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 16s
This commit is contained in:
@@ -111,10 +111,8 @@ $manufacturers = $stmt_man_load->get_result()->fetch_all(MYSQLI_ASSOC);
|
||||
$stmt_man_load->close();
|
||||
|
||||
// Load Articles for Linked Compartments
|
||||
// Filter: Show all articles (or maybe only containers/bags? User said "any"). Let's load all.
|
||||
$hh_ids = [$user_id];
|
||||
if ($household_id) {
|
||||
// Get all users in household
|
||||
$stmt_hhm = $conn->prepare("SELECT id FROM users WHERE household_id = ?");
|
||||
$stmt_hhm->bind_param("i", $household_id);
|
||||
$stmt_hhm->execute();
|
||||
@@ -124,7 +122,7 @@ if ($household_id) {
|
||||
$placeholders = implode(',', array_fill(0, count($hh_ids), '?'));
|
||||
$types_hh = str_repeat('i', count($hh_ids));
|
||||
$stmt_arts = $conn->prepare("SELECT id, name, weight_grams, image_url FROM articles WHERE user_id IN ($placeholders) OR household_id = ? ORDER BY name ASC");
|
||||
$params_arts = array_merge($hh_ids, [$household_id ?: 0]); // 0 if null
|
||||
$params_arts = array_merge($hh_ids, [$household_id ?: 0]);
|
||||
$types_arts = $types_hh . 'i';
|
||||
$stmt_arts->bind_param($types_arts, ...$params_arts);
|
||||
$stmt_arts->execute();
|
||||
@@ -136,7 +134,6 @@ $stmt_arts->close();
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$name = trim($_POST['name']);
|
||||
|
||||
// Manufacturer Logic
|
||||
$manufacturer = '';
|
||||
if (isset($_POST['manufacturer_select'])) {
|
||||
if ($_POST['manufacturer_select'] === 'new') {
|
||||
@@ -173,7 +170,6 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$share_household = isset($_POST['share_household']) ? 1 : 0;
|
||||
$product_url_input = trim($_POST['product_url'] ?? '');
|
||||
|
||||
// Image Handling
|
||||
$image_url_for_db = $image_url;
|
||||
$pasted_image = $_POST['pasted_image_data'] ?? '';
|
||||
$url_image = trim($_POST['image_url_input'] ?? '');
|
||||
@@ -198,12 +194,10 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$final_household_id = ($share_household && $household_id) ? $household_id : NULL;
|
||||
|
||||
if ($backpack_id > 0) {
|
||||
// Update
|
||||
$stmt = $conn->prepare("UPDATE backpacks SET name=?, manufacturer=?, model=?, weight_grams=?, volume_liters=?, household_id=?, image_url=?, product_url=? WHERE id=? AND user_id=?");
|
||||
$stmt->bind_param("sssiisssii", $name, $manufacturer, $model, $weight, $volume, $final_household_id, $image_url_for_db, $product_url_input, $backpack_id, $user_id);
|
||||
$stmt->execute();
|
||||
} else {
|
||||
// Insert
|
||||
$stmt = $conn->prepare("INSERT INTO backpacks (user_id, household_id, name, manufacturer, model, weight_grams, volume_liters, image_url, product_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("iisssiiss", $user_id, $final_household_id, $name, $manufacturer, $model, $weight, $volume, $image_url_for_db, $product_url_input);
|
||||
$stmt->execute();
|
||||
@@ -211,14 +205,12 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
}
|
||||
|
||||
// Handle Compartments
|
||||
// Arrays: comp_ids, comp_types (text/article), comp_names, comp_articles
|
||||
if (isset($_POST['comp_types'])) {
|
||||
$types = $_POST['comp_types'];
|
||||
$ids = $_POST['comp_ids'] ?? [];
|
||||
$names = $_POST['comp_names'] ?? [];
|
||||
$articles = $_POST['comp_articles'] ?? [];
|
||||
|
||||
// Get existing IDs
|
||||
$existing_ids = [];
|
||||
if($backpack_id > 0){
|
||||
$stmt_check = $conn->prepare("SELECT id FROM backpack_compartments WHERE backpack_id = ?");
|
||||
@@ -238,8 +230,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
if ($c_type === 'article') {
|
||||
$c_article_id = intval($articles[$i] ?? 0);
|
||||
if ($c_article_id <= 0) continue; // Skip invalid
|
||||
// Get name from article for display purposes (fallback)
|
||||
if ($c_article_id <= 0) continue;
|
||||
foreach($all_articles as $art) {
|
||||
if ($art['id'] == $c_article_id) {
|
||||
$c_name = $art['name'];
|
||||
@@ -252,20 +243,17 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
}
|
||||
|
||||
if ($c_id > 0 && in_array($c_id, $existing_ids)) {
|
||||
// Update
|
||||
$stmt_up = $conn->prepare("UPDATE backpack_compartments SET name = ?, sort_order = ?, linked_article_id = ? WHERE id = ?");
|
||||
$stmt_up->bind_param("siii", $c_name, $i, $c_article_id, $c_id);
|
||||
$stmt_up->execute();
|
||||
$kept_ids[] = $c_id;
|
||||
} else {
|
||||
// Insert
|
||||
$stmt_in = $conn->prepare("INSERT INTO backpack_compartments (backpack_id, name, sort_order, linked_article_id) VALUES (?, ?, ?, ?)");
|
||||
$stmt_in->bind_param("isii", $backpack_id, $c_name, $i, $c_article_id);
|
||||
$stmt_in->execute();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removed
|
||||
foreach ($existing_ids as $ex_id) {
|
||||
if (!in_array($ex_id, $kept_ids)) {
|
||||
$conn->query("DELETE FROM backpack_compartments WHERE id = $ex_id");
|
||||
@@ -380,15 +368,17 @@ require_once 'header.php';
|
||||
</select>
|
||||
|
||||
<!-- Text Input -->
|
||||
<input type="text" name="comp_names[]" class="form-control name-input" value="Hauptfach" placeholder="Fachname">
|
||||
<input type="text" name="comp_names[]" class="form-control name-input" placeholder="Fachname">
|
||||
|
||||
<!-- Article Select (Hidden initially) -->
|
||||
<select name="comp_articles[]" class="form-select article-select" style="display:none;">
|
||||
<option value="">Artikel wählen...</option>
|
||||
<?php foreach($all_articles as $art): ?>
|
||||
<option value="<?php echo $art['id']; ?>"><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<!-- Article Select -->
|
||||
<div class="flex-grow-1 article-select-wrapper" style="display:none;">
|
||||
<select name="comp_articles[]" class="form-select article-select tom-select-init">
|
||||
<option value="">Artikel wählen...</option>
|
||||
<?php foreach($all_articles as $art): ?>
|
||||
<option value="<?php echo $art['id']; ?>" data-src="<?php echo !empty($art['image_url']) ? htmlspecialchars($art['image_url']) : ''; ?>"><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="comp_ids[]" value="0">
|
||||
<button type="button" class="btn btn-outline-danger btn-remove-comp"><i class="fas fa-times"></i></button>
|
||||
@@ -416,7 +406,7 @@ require_once 'header.php';
|
||||
<?php foreach($all_articles as $art):
|
||||
$sel = ($is_article && $art['id'] == $comp['linked_article_id']) ? 'selected' : '';
|
||||
?>
|
||||
<option value="<?php echo $art['id']; ?>" <?php echo $sel; ?>><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<option value="<?php echo $art['id']; ?>" <?php echo $sel; ?> data-src="<?php echo !empty($art['image_url']) ? htmlspecialchars($art['image_url']) : ''; ?>"><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@@ -475,7 +465,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
|
||||
// Template for new row (with placeholders)
|
||||
// Note: We use a class 'tom-select-init' to mark selects that need init
|
||||
const rowTemplate = `
|
||||
<div class="compartment-row card mb-2">
|
||||
<div class="card-body p-2">
|
||||
@@ -492,7 +481,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
<select name="comp_articles[]" class="form-select article-select tom-select-init">
|
||||
<option value="">Artikel wählen...</option>
|
||||
<?php foreach($all_articles as $art): ?>
|
||||
<option value="<?php echo $art['id']; ?>"><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<option value="<?php echo $art['id']; ?>" data-src="<?php echo !empty($art['image_url']) ? htmlspecialchars($art['image_url']) : ''; ?>"><?php echo htmlspecialchars($art['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
@@ -506,26 +495,50 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
document.getElementById('add-compartment').addEventListener('click', function() {
|
||||
container.insertAdjacentHTML('beforeend', rowTemplate);
|
||||
// Init new elements
|
||||
const newRow = container.lastElementChild;
|
||||
initRowLogic(newRow);
|
||||
});
|
||||
|
||||
function initTomSelect(select) {
|
||||
if (select.tomselect) return;
|
||||
new TomSelect(select, {
|
||||
create: false,
|
||||
sortField: { field: "text", direction: "asc" },
|
||||
dropdownParent: 'body',
|
||||
render: {
|
||||
option: function(data, escape) {
|
||||
let src = data.src || '';
|
||||
return `<div>
|
||||
${src ? `<img src="${src}" style="width:24px;height:24px;object-fit:cover;margin-right:8px;vertical-align:middle;">` : ''}
|
||||
<span>${escape(data.text)}</span>
|
||||
</div>`;
|
||||
},
|
||||
item: function(data, escape) {
|
||||
let src = data.src || '';
|
||||
return `<div>
|
||||
${src ? `<img src="${src}" style="width:20px;height:20px;object-fit:cover;margin-right:6px;vertical-align:middle;">` : ''}
|
||||
<span>${escape(data.text)}</span>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initRowLogic(row) {
|
||||
const typeSelect = row.querySelector('.type-select');
|
||||
const nameInput = row.querySelector('.name-input');
|
||||
const artWrapper = row.querySelector('.article-select-wrapper');
|
||||
const artSelect = row.querySelector('.article-select');
|
||||
|
||||
// Type Toggle Logic
|
||||
typeSelect.addEventListener('change', function() {
|
||||
if (this.value === 'article') {
|
||||
nameInput.style.display = 'none';
|
||||
artWrapper.style.display = 'block';
|
||||
// Init TomSelect if not yet done
|
||||
if (artSelect.classList.contains('tom-select-init') && !artSelect.tomselect) {
|
||||
new TomSelect(artSelect, { create: false, sortField: { field: "text", direction: "asc" } });
|
||||
initTomSelect(artSelect);
|
||||
artSelect.classList.remove('tom-select-init');
|
||||
} else if (artSelect && !artSelect.tomselect) {
|
||||
initTomSelect(artSelect);
|
||||
}
|
||||
} else {
|
||||
nameInput.style.display = 'block';
|
||||
@@ -533,9 +546,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize TomSelect for existing items (if visible) or prepare them
|
||||
if (artSelect && !artSelect.tomselect) {
|
||||
new TomSelect(artSelect, { create: false, sortField: { field: "text", direction: "asc" } });
|
||||
// Init if already visible (editing mode)
|
||||
if (artSelect && !artSelect.tomselect && artWrapper.style.display !== 'none') {
|
||||
initTomSelect(artSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,7 +561,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
});
|
||||
|
||||
// Image Handling Logic (same as before)
|
||||
// Image Handling Logic
|
||||
const imageFileInput = document.getElementById('image_file');
|
||||
const imagePreview = document.getElementById('imagePreview');
|
||||
const pasteArea = document.getElementById('pasteArea');
|
||||
@@ -588,4 +601,4 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'footer.php'; ?>
|
||||
<?php require_once 'footer.php'; ?>
|
||||
|
||||
Reference in New Issue
Block a user