112 lines
4.5 KiB
HTML
112 lines
4.5 KiB
HTML
{% extends "admin/base.html" %}
|
|
{% load static %}
|
|
|
|
{% block html_attrs %}
|
|
lang="fa" dir="rtl"
|
|
{% endblock %}
|
|
|
|
|
|
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static 'override.css' %}" />
|
|
<link rel="stylesheet" type="text/css" href="{% static 'fonts.css' %}" />
|
|
<link rel="stylesheet" type="text/css" href="{% static 'rtl2.css' %}" />
|
|
{% endblock %}
|
|
{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
|
|
|
|
{% block branding %}
|
|
<h1 id="site-name"><a href="{% url 'admin:index' %}">مدیریت هی ملز</a></h1>
|
|
{% endblock %}
|
|
|
|
{% block extrahead %}
|
|
{% if plausible_domain %}
|
|
<script defer data-domain="{{ plausible_domain }}" src="https://plausible.io/js/script.js"></script>
|
|
{% endif %}
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
// Format all existing inputs
|
|
formatAllPriceInputs();
|
|
|
|
// 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 cursorPosition = input.selectionStart;
|
|
const oldValue = input.value;
|
|
const raw = oldValue.replace(/,/g, "");
|
|
const formatted = format(raw);
|
|
|
|
if (oldValue !== formatted) {
|
|
// Count commas before cursor in old value
|
|
const commasBeforeCursor = (oldValue.substring(0, cursorPosition).match(/,/g) || []).length;
|
|
// Count commas before cursor position in raw value
|
|
const rawCursorPosition = cursorPosition - commasBeforeCursor;
|
|
|
|
// Set the formatted value
|
|
input.value = formatted;
|
|
|
|
// Calculate new cursor position
|
|
let newCursorPosition = 0;
|
|
let rawIndex = 0;
|
|
|
|
for (let i = 0; i < formatted.length && rawIndex < rawCursorPosition; i++) {
|
|
if (formatted[i] !== ',') {
|
|
rawIndex++;
|
|
}
|
|
newCursorPosition++;
|
|
}
|
|
|
|
input.setSelectionRange(newCursorPosition, newCursorPosition);
|
|
}
|
|
}
|
|
});
|
|
|
|
// 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 formatAllPriceInputs() {
|
|
document.querySelectorAll(".price-input").forEach((input) => {
|
|
input.value = format(input.value);
|
|
});
|
|
}
|
|
|
|
function format(value) {
|
|
if (!value) return "";
|
|
return value.replace(/\D/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
}
|
|
</script>
|
|
{% endblock %}
|