Files
Simple-Wishlist/js/wishlist.js

406 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// js/wishlist.js
(function () {
"use strict";
// ===== Helper =====
function $(sel, root) {
return (root || document).querySelector(sel);
}
function $all(sel, root) {
return Array.from((root || document).querySelectorAll(sel));
}
// ===== Sort direkt submitten =====
const sortSel = $("#sortby");
if (sortSel && sortSel.form) {
sortSel.addEventListener("change", function () {
this.form.submit();
});
}
// ===== Reservation Modal =====
const reservationModal = $("#reservationModal");
if (reservationModal) {
reservationModal.addEventListener("show.bs.modal", function (ev) {
const btn = ev.relatedTarget;
if (!btn) return;
const wishid = btn.getAttribute("data-wishid");
const reserved = btn.getAttribute("data-reserved");
$("#modal-wishid", reservationModal).value = wishid || "";
$("#modal-reservedstat", reservationModal).value = reserved || "";
const submitBtn = $("#reservation-submit", reservationModal);
const titleEl = $("#reservationModalLabel", reservationModal);
const infoEl = $("#ReservationInfoText", reservationModal);
if (reserved === "1") {
submitBtn.textContent = "Reservierung aufheben";
titleEl.textContent = "Reservierung aufheben";
if (infoEl) infoEl.style.display = "none";
} else {
submitBtn.textContent = "Reservieren";
titleEl.textContent = "Wunsch reservieren";
if (infoEl) infoEl.style.display = "";
}
});
}
// ===== Delete Modal =====
const deleteModal = $("#deleteModal");
if (deleteModal) {
deleteModal.addEventListener("show.bs.modal", function (ev) {
const btn = ev.relatedTarget;
if (!btn) return;
const card = btn.closest(".card");
const title = card
? card.querySelector(".card-title")?.textContent?.trim() || ""
: "";
const wishid = btn.getAttribute("data-wishid") || "";
const idInput = deleteModal.querySelector(
'#DelWhishID, #WhishID, input[name="WhishID"]'
);
const titleEl = deleteModal.querySelector(
"#del-whish-title, #whish-title"
);
if (idInput) idInput.value = wishid;
if (titleEl) titleEl.textContent = title || "Wunsch";
});
}
// ===== Push Prio Modal =====
const prioModal = $("#pushprioModal");
if (prioModal) {
prioModal.addEventListener("show.bs.modal", function (ev) {
const btn = ev.relatedTarget;
if (!btn) return;
const card = btn.closest(".card");
const title = card
? card.querySelector(".card-title")?.textContent?.trim() || ""
: "";
const wishid = btn.getAttribute("data-wishid") || "";
const idInput = prioModal.querySelector(
'#PrioWhishID, #WhishID, input[name="WhishID"]'
);
const titleEl = prioModal.querySelector(
"#prio-whish-title, #whish-title"
);
if (idInput) idInput.value = wishid;
if (titleEl) titleEl.textContent = title || "Wunsch";
});
}
// ===== Add/Edit Item Modal =====
const itemModal = $("#itemModal");
let _currentPreviewObjectUrl = null;
function revokePreviewUrl() {
if (_currentPreviewObjectUrl) {
try {
URL.revokeObjectURL(_currentPreviewObjectUrl);
} catch (e) {}
_currentPreviewObjectUrl = null;
}
}
if (itemModal) {
itemModal.addEventListener("show.bs.modal", function (ev) {
const btn = ev.relatedTarget;
if (!btn) return;
const mode = btn.getAttribute("data-mode") || "add";
const titleEl = $("#itemModalTitle", itemModal);
const actionEl = $("#ItemAction", itemModal);
const submitEl = $("#ItemSubmitBtn", itemModal);
const removeWrap = $("#RemoveImageWrap", itemModal);
const removeChk = $("#RemoveImage", itemModal);
// Felder
const fTitle = $("#ItemTitle", itemModal);
const fDesc = $("#ItemDescription", itemModal);
const fPrice = $("#ItemPrice", itemModal);
const fLink = $("#ItemLink", itemModal);
const fId = $("#WhishID", itemModal);
const fQty = $("#ItemQty", itemModal);
// Bild-Felder
const fImgUrl = $("#ItemImageUrl", itemModal);
const fImgFile = $("#ItemImageFile", itemModal);
const pasteZone = $("#PasteZone", itemModal);
const pasteVal = $("#ItemImagePaste", itemModal);
const pasteName = $("#ItemImagePasteName", itemModal);
const prevWrap = $("#ImgPreviewWrap", itemModal);
const prevImg = $("#ImgPreview", itemModal);
const pasteActivator = $("#PasteActivator", itemModal);
// Preview-Styling erzwingen (falls keine CSS-Regel vorhanden)
if (prevWrap) {
prevWrap.style.maxHeight = "240px";
prevWrap.style.overflow = "hidden";
prevWrap.style.border = "1px solid rgba(0,0,0,.1)";
prevWrap.style.borderRadius = ".5rem";
prevWrap.style.padding = ".5rem";
prevWrap.style.background = "#fff";
}
if (prevImg) {
prevImg.style.maxWidth = "100%";
prevImg.style.maxHeight = "220px";
prevImg.style.objectFit = "contain";
prevImg.classList.add("img-fluid", "border", "rounded", "w-100");
}
function showPreview(src) {
revokePreviewUrl();
if (!prevWrap || !prevImg) return;
if (!src) {
prevWrap.style.display = "none";
prevImg.removeAttribute("src");
return;
}
prevImg.src = src;
prevWrap.style.display = "block";
if (src.startsWith("blob:")) _currentPreviewObjectUrl = src;
}
function clearUrl() {
if (fImgUrl) fImgUrl.value = "";
}
function clearFile() {
if (fImgFile) fImgFile.value = "";
}
function clearPaste() {
if (pasteVal) pasteVal.value = "";
if (pasteName) pasteName.value = "clipboard.png";
if (pasteZone) {
pasteZone.innerHTML = "";
pasteZone.setAttribute("data-ph-active", "1");
}
}
function clearPreviewAndInputs() {
showPreview("");
clearUrl();
clearFile();
clearPaste();
}
function focusPasteCatcher() {
if (!pasteZone) return;
// kurz sichtbar machen, fokus holen, dann wieder verstecken
pasteZone.classList.remove("visually-hidden");
pasteZone.focus();
// cursor ans ende
const sel = window.getSelection();
if (sel && sel.rangeCount === 0) {
const r = document.createRange();
r.selectNodeContents(pasteZone);
r.collapse(false);
sel.removeAllRanges();
sel.addRange(r);
}
// wieder verstecken Fokus bleibt (Browser lässt Paste trotzdem zu)
setTimeout(() => pasteZone.classList.add("visually-hidden"), 10);
}
// —— Modal immer CLEAN beim Öffnen ——
clearPreviewAndInputs();
if (mode === "edit") {
titleEl.textContent = "Wunsch bearbeiten";
actionEl.value = "edit";
submitEl.textContent = "Speichern";
if (removeWrap) removeWrap.style.display = "";
if (removeChk) removeChk.checked = false;
const wishid = btn.getAttribute("data-wishid") || "-1";
const dTitle = btn.getAttribute("data-title") || "";
const dDesc = btn.getAttribute("data-description") || "";
const dPrice = btn.getAttribute("data-price") || "";
const dLink = btn.getAttribute("data-link") || "";
const dQty = btn.getAttribute("data-qty") || "1";
if (fId) fId.value = wishid;
if (fTitle) fTitle.value = dTitle;
if (fDesc) fDesc.value = dDesc;
if (fPrice) fPrice.value = dPrice;
if (fLink) fLink.value = dLink;
if (fQty) fQty.value = dQty;
} else {
titleEl.textContent = "Wunsch hinzufügen";
actionEl.value = "add";
submitEl.textContent = "Hinzufügen";
if (fId) fId.value = "-1";
if (fTitle) fTitle.value = "";
if (fDesc) fDesc.value = "";
if (fPrice) fPrice.value = "";
if (fLink) fLink.value = "";
if (fQty) fQty.value = "1";
if (removeWrap) removeWrap.style.display = "none";
if (removeChk) removeChk.checked = false;
}
// --- Bild-URL
if (fImgUrl) {
fImgUrl.addEventListener(
"input",
() => {
const val = fImgUrl.value.trim();
if (val !== "") {
clearFile();
clearPaste();
showPreview(val);
} else showPreview("");
},
{ once: true }
);
}
// --- Datei-Upload
if (fImgFile) {
fImgFile.addEventListener(
"change",
() => {
if (fImgFile.files && fImgFile.files[0]) {
const f = fImgFile.files[0];
if (f.size > 8 * 1024 * 1024) {
alert("Datei ist größer als 8 MB.");
fImgFile.value = "";
showPreview("");
return;
}
clearUrl();
clearPaste();
const blobUrl = URL.createObjectURL(f);
showPreview(blobUrl);
} else {
showPreview("");
}
},
{ once: true }
);
}
// --- Paste aus Zwischenablage
if (pasteZone) {
pasteZone.setAttribute(
"data-placeholder",
pasteZone.getAttribute("data-placeholder") ||
"Hier klicken und dann Strg+V / Cmd+V"
);
pasteZone.setAttribute("data-ph-active", "1");
pasteZone.addEventListener(
"focus",
() => {
if (pasteZone.getAttribute("data-ph-active") === "1") {
pasteZone.innerHTML = "";
pasteZone.removeAttribute("data-ph-active");
}
},
{ once: true }
);
pasteZone.addEventListener("blur", () => {
if (pasteZone.innerText.trim() === "") {
pasteZone.innerHTML = "";
pasteZone.setAttribute("data-ph-active", "1");
}
});
// verhindert, dass Text-Schnipsel sichtbar werden
pasteZone.addEventListener("input", () => {
pasteZone.textContent = "";
});
// keine Drops zulassen
["dragover", "drop"].forEach((evName) => {
pasteZone.addEventListener(evName, (e) => {
e.preventDefault();
e.stopPropagation();
});
});
pasteZone.addEventListener(
"paste",
(ev) => {
const items =
ev.clipboardData && ev.clipboardData.items
? ev.clipboardData.items
: [];
let imgItem = null;
for (let i = 0; i < items.length; i++) {
const t = items[i].type || "";
if (t.startsWith("image/")) {
imgItem = items[i];
break;
}
}
// nur Bilder erlaubt
if (!imgItem) {
ev.preventDefault();
// optional Hinweis
alert("Bitte nur Bilder einfügen (z. B. über „Bild kopieren“).");
return;
}
ev.preventDefault();
const blob = imgItem.getAsFile();
if (!blob) return;
if (blob.size > 8 * 1024 * 1024) {
alert("Paste-Bild ist größer als 8 MB.");
return;
}
const ext =
blob.type && blob.type.split("/")[1]
? blob.type.split("/")[1]
: "png";
if (pasteName) pasteName.value = "clipboard." + ext;
const reader = new FileReader();
reader.onload = function () {
const dataUrl = reader.result; // data:image/*;base64,...
if (pasteVal) pasteVal.value = dataUrl;
clearUrl();
clearFile();
showPreview(dataUrl);
};
reader.readAsDataURL(blob);
},
{ once: true }
);
}
if (pasteActivator) {
pasteActivator.addEventListener(
"click",
() => {
// andere Inputs leeren, Preview resetten
clearUrl();
clearFile();
// Fokus in den versteckten Paste-Catcher
focusPasteCatcher();
},
{ once: true }
);
}
// Beim Schließen: wirklich ALLES wieder clean + Blob-URL freigeben
itemModal.addEventListener(
"hidden.bs.modal",
() => {
revokePreviewUrl();
if (prevWrap) prevWrap.style.display = "none";
if (prevImg) prevImg.removeAttribute("src");
clearUrl();
clearFile();
clearPaste();
if (removeChk) removeChk.checked = false;
},
{ once: true }
);
});
}
})();