Improve forms

This commit is contained in:
Edgar P. Burkhart 2025-01-01 15:39:18 +01:00
parent 221dbb196e
commit eeb5f4f04f
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
4 changed files with 133 additions and 68 deletions

View file

@ -10,3 +10,9 @@ class NummiForm(forms.ModelForm):
def __init__(self, *args, user, **kwargs): def __init__(self, *args, user, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def get_context(self):
context = super().get_context()
context["fieldsets"] = [[[field] for field in self]]
return context

View file

@ -6,42 +6,101 @@ form ul.errorlist {
} }
form { form {
max-width: 32rem;
display: grid; display: grid;
grid-gap: var(--gap); grid-gap: var(--gap);
grid-template-columns: repeat(auto-fill, 32rem);
@media (width < 1024px) {
grid-template-columns: 1fr;
}
p.field { .column {
display: grid; display: grid;
grid-auto-rows: min-content; grid-gap: var(--gap);
border: 1px solid var(--gray);
padding: 0.5rem;
margin: 0;
&:has(> input, > select, > textarea) > label { .fieldset {
font-size: 0.8rem; display: grid;
line-height: 0.8rem; grid-auto-columns: 1fr;
z-index: 10; grid-auto-flow: column;
grid-gap: var(--gap);
padding: 0;
margin: 0;
border: none;
} }
> input, p.field {
> select, display: grid;
> textarea { grid-auto-rows: min-content;
border: 1px solid var(--gray);
padding: 0.5rem;
margin: 0;
&:has(> textarea) {
grid-template-rows: min-content 1fr;
}
&:has(> input, > select, > textarea) > label {
font-size: 0.8rem;
line-height: 0.8rem;
z-index: 10;
}
> input,
> select,
> textarea {
font: inherit;
line-height: initial;
border: none;
border-bottom: 1px solid var(--gray);
background: none;
z-index: 1;
&[name="value"] {
font-size: 1.5rem;
text-align: right;
}
&:focus {
outline: none;
background: var(--bg-01);
}
}
}
}
.buttons {
grid-column: 1 / -1;
display: grid;
grid-auto-columns: min-content;
grid-gap: var(--gap);
align-items: baseline;
& > * {
grid-row: 1;
}
input {
font: inherit; font: inherit;
line-height: initial; line-height: 1.5;
border: none; border-radius: var(--radius);
border-bottom: 1px solid var(--gray); padding: 0 var(--gap);
background: none; cursor: pointer;
z-index: 1;
&[name="value"] { &:hover {
font-size: 1.5rem; text-decoration: underline;
text-align: right;
} }
&[type="submit"] {
&:focus { border: 0.1rem solid var(--green);
outline: none; background: var(--green-1);
background: var(--bg-01); grid-column: 1;
} }
&[type="reset"] {
border: 0.1rem solid var(--red);
background: var(--red-1);
grid-column: 2;
}
}
a.del {
color: var(--red);
grid-column: 3;
} }
} }
} }
@ -60,40 +119,3 @@ table.file-input {
text-align: left; text-align: left;
} }
} }
.buttons {
display: grid;
grid-auto-columns: min-content;
grid-gap: var(--gap);
align-items: baseline;
& > * {
grid-row: 1;
}
input {
font: inherit;
line-height: 1.5;
border-radius: var(--radius);
padding: 0 var(--gap);
cursor: pointer;
&:hover {
text-decoration: underline;
}
&[type="submit"] {
border: 0.1rem solid var(--green);
background: var(--green-1);
grid-column: 1;
}
&[type="reset"] {
border: 0.1rem solid var(--red);
background: var(--red-1);
grid-column: 2;
}
}
a.del {
color: var(--red);
grid-column: 3;
}
}

View file

@ -6,12 +6,30 @@
{% for error in form.non_field_errors %}<li>{{ error }}</li>{% endfor %} {% for error in form.non_field_errors %}<li>{{ error }}</li>{% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% for field in form %} {% for group in fieldsets %}
{% if field.errors %}<p class="error">{{ field.errors }}</p>{% endif %} <div class="column">
<p class="field"> {% for fieldset in group %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label> {% if fieldset|length > 1 %}
{{ field }} <div class="fieldset">
</p> {% for field in fieldset %}
{% if field.errors %}<p class="error">{{ field.errors }}</p>{% endif %}
<p class="field">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
</p>
{% endfor %}
</div>
{% else %}
{% with fieldset.0 as field %}
{% if field.errors %}<p class="error">{{ field.errors }}</p>{% endif %}
<p class="field">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
</p>
{% endwith %}
{% endif %}
{% endfor %}
</div>
{% endfor %} {% endfor %}
<div class="buttons"> <div class="buttons">
{% block buttons %} {% block buttons %}

View file

@ -35,9 +35,28 @@ class TransactionForm(NummiForm):
self.fields["payment"].widget = DatalistInput( self.fields["payment"].widget = DatalistInput(
options=get_datalist(_user, "payment") options=get_datalist(_user, "payment")
) )
if _disable_statement: if _disable_statement:
self.fields["statement"].disabled = True self.fields["statement"].disabled = True
def get_context(self):
context = super().get_context()
context["fieldsets"] = [
[
[self["statement"]],
[self["name"]],
[self["value"]],
[self["date"], self["real_date"]],
[self["category"]],
[self["trader"], self["payment"]],
],
[
[self["description"]],
],
]
return context
class InvoiceForm(NummiForm): class InvoiceForm(NummiForm):
prefix = "invoice" prefix = "invoice"