parent
0cb4a681f1
commit
ff519ea7d1
5 changed files with 111 additions and 2 deletions
|
@ -1,3 +1,11 @@
|
|||
@keyframes border-pulse {
|
||||
from {
|
||||
border-color: var(--green);
|
||||
}
|
||||
to {
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
gap: 0.5rem;
|
||||
|
@ -90,6 +98,9 @@ form {
|
|||
&:has(~ ul.errorlist) {
|
||||
border-color: var(--red);
|
||||
}
|
||||
&.autocompleted:not(.mod) {
|
||||
border-bottom-color: var(--green);
|
||||
}
|
||||
|
||||
&:not([type="checkbox"]) {
|
||||
width: 100%;
|
||||
|
|
|
@ -44,7 +44,6 @@ for (let form of forms) {
|
|||
);
|
||||
|
||||
function setIcon(event) {
|
||||
console.log(input.value);
|
||||
icon.className = `ri-${
|
||||
icons.includes(input.value) ? input.value : "square"
|
||||
}-line`;
|
||||
|
@ -55,6 +54,75 @@ for (let form of forms) {
|
|||
setTimeout(setIcon, 0);
|
||||
});
|
||||
}
|
||||
|
||||
let ac_json = form.querySelector("#autocomplete");
|
||||
if (ac_json) {
|
||||
let autocomplete_data = JSON.parse(ac_json.textContent);
|
||||
let fields = form.querySelectorAll("[name]");
|
||||
function clearMod(event) {
|
||||
event.target.classList.add("mod");
|
||||
event.target.removeEventListener("input", clearMod);
|
||||
}
|
||||
function setMod() {
|
||||
for (let f of fields) {
|
||||
f.addEventListener("input", clearMod);
|
||||
}
|
||||
}
|
||||
setMod();
|
||||
form.addEventListener("reset", (event) => {
|
||||
for (let f of fields) {
|
||||
f.classList.remove("mod", "autocompleted");
|
||||
}
|
||||
setMod();
|
||||
});
|
||||
|
||||
let old_values = [];
|
||||
|
||||
let field = form.querySelector(`[name="${autocomplete_data.field}"]`);
|
||||
field.addEventListener("change", (event) => {
|
||||
if (field.value in autocomplete_data.data) {
|
||||
old_values = [];
|
||||
for (let comp of autocomplete_data.data[field.value]) {
|
||||
let f = form.querySelector(`[name="${comp.field}"]`);
|
||||
if (!f.classList.contains("mod")) {
|
||||
old_values.push({ field: f, value: f.value });
|
||||
|
||||
f.value = comp.value;
|
||||
f.dispatchEvent(new Event("input"));
|
||||
f.animate([{ borderColor: "var(--green)" }, {}], 750);
|
||||
f.classList.remove("mod");
|
||||
f.classList.add("autocompleted");
|
||||
f.addEventListener("input", clearMod);
|
||||
function ccAutocomplete(event) {
|
||||
document.removeEventListener("keyup", cancelAutocomplete);
|
||||
for (comp of old_values) {
|
||||
comp.field.removeEventListener("input", ccAutocomplete);
|
||||
}
|
||||
}
|
||||
f.addEventListener("input", ccAutocomplete);
|
||||
}
|
||||
}
|
||||
function cancelAutocomplete(event) {
|
||||
if (event.code == "Escape") {
|
||||
for (comp of old_values) {
|
||||
let f = comp.field;
|
||||
f.value = comp.value;
|
||||
f.dispatchEvent(new Event("input"));
|
||||
f.animate([{ borderColor: "var(--red)" }, {}], 750);
|
||||
f.classList.remove("mod");
|
||||
f.classList.remove("autocompleted");
|
||||
f.addEventListener("input", clearMod);
|
||||
}
|
||||
document.removeEventListener("keyup", cancelAutocomplete);
|
||||
}
|
||||
}
|
||||
document.addEventListener("keyup", cancelAutocomplete);
|
||||
form.addEventListener("reset", (event) => {
|
||||
document.removeEventListener("keyup", cancelAutocomplete);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let accounts = document.querySelector("dl.accounts");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% load i18n %}
|
||||
{% load main_extras %}
|
||||
{% block fields %}
|
||||
{% if form.autocomplete %}{{ form.autocomplete|json_script:"autocomplete" }}{% endif %}
|
||||
{% if form.non_field_errors %}
|
||||
<ul class="errorlist">
|
||||
{% for error in form.non_field_errors %}<li>{{ error }}</li>{% endfor %}
|
||||
|
|
|
@ -48,6 +48,7 @@ class TransactionForm(NummiForm):
|
|||
def __init__(self, *args, **kwargs):
|
||||
_user = kwargs.get("user")
|
||||
_disable_statement = kwargs.pop("disable_statement", False)
|
||||
_autocomplete = kwargs.pop("autocomplete", False)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fields["category"].queryset = self.fields["category"].queryset.filter(
|
||||
|
@ -71,6 +72,34 @@ class TransactionForm(NummiForm):
|
|||
),
|
||||
}
|
||||
|
||||
if _autocomplete:
|
||||
self.autocomplete = {
|
||||
"field": "name",
|
||||
"data": {
|
||||
t.name: [
|
||||
{
|
||||
"field": "value",
|
||||
"value": t.value,
|
||||
},
|
||||
{
|
||||
"field": "category",
|
||||
"value": t.category.id if t.category else "",
|
||||
},
|
||||
{
|
||||
"field": "trader",
|
||||
"value": t.trader,
|
||||
},
|
||||
{
|
||||
"field": "payment",
|
||||
"value": t.payment,
|
||||
},
|
||||
]
|
||||
for t in _user.transaction_set.order_by("name", "-date").distinct(
|
||||
"name"
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
if _disable_statement:
|
||||
self.fields["statement"].disabled = True
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class TransactionCreateView(NummiCreateView):
|
|||
def get_form_kwargs(self):
|
||||
if "statement" in self.kwargs:
|
||||
return super().get_form_kwargs() | {"disable_statement": True}
|
||||
return super().get_form_kwargs()
|
||||
return super().get_form_kwargs() | {"autocomplete": True}
|
||||
|
||||
|
||||
class InvoiceCreateView(NummiCreateView):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue