From 48dcdda7e5b24dbc42b76ba9dccb9cd1b1975790 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Sat, 20 Dec 2025 20:12:58 +0330 Subject: [PATCH] refactor price input formatting logic and improve event handling --- backend/core/static/price-format.js | 73 +++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/backend/core/static/price-format.js b/backend/core/static/price-format.js index 0202853..bf968e6 100644 --- a/backend/core/static/price-format.js +++ b/backend/core/static/price-format.js @@ -1,28 +1,63 @@ document.addEventListener("DOMContentLoaded", () => { - initPriceInputs(document); + // Format all existing inputs + formatAllPriceInputs(); - document.addEventListener("formset:added", (event) => { - initPriceInputs(event.target); + // Use event delegation for input events on price-input fields + document.addEventListener("input", (event) => { + if (event.target.classList.contains("price-input")) { + const input = event.target; + const cursor = input.selectionStart; + const raw = input.value.replace(/,/g, ""); + const formatted = format(raw); + + if (input.value !== formatted) { + input.value = formatted; + input.setSelectionRange(cursor, cursor); + } + } + }); + + // Use event delegation for focus events to format on focus + document.addEventListener("focus", (event) => { + if (event.target.classList.contains("price-input")) { + event.target.value = format(event.target.value); + } + }, true); + + // Use event delegation for form submit + document.addEventListener("submit", (event) => { + event.target.querySelectorAll(".price-input").forEach((input) => { + input.value = input.value.replace(/,/g, ""); + }); + }); + + // Use MutationObserver to format newly added inputs + const observer = new MutationObserver((mutations) => { + let hasNewInputs = false; + mutations.forEach((mutation) => { + mutation.addedNodes.forEach((node) => { + if (node.nodeType === 1) { + if (node.classList?.contains("price-input") || + node.querySelectorAll?.(".price-input").length > 0) { + hasNewInputs = true; + } + } + }); + }); + if (hasNewInputs) { + formatAllPriceInputs(); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true }); }); -function initPriceInputs(root) { - root.querySelectorAll(".price-input").forEach((input) => { - if (input.dataset.formatted) return; - input.dataset.formatted = "true"; - +function formatAllPriceInputs() { + document.querySelectorAll(".price-input").forEach((input) => { input.value = format(input.value); - - input.addEventListener("input", () => { - const cursor = input.selectionStart; - const raw = input.value.replace(/,/g, ""); - input.value = format(raw); - input.setSelectionRange(cursor, cursor); - }); - - input.form?.addEventListener("submit", () => { - input.value = input.value.replace(/,/g, ""); - }); }); }