More code reuse + inline form rendering

This commit is contained in:
Tobias Kunze 2025-03-20 08:58:05 +01:00
parent b36ebcf5ff
commit eae01c74c7
2 changed files with 49 additions and 52 deletions

View file

@ -1,9 +1,14 @@
from servala.frontend.forms.renderers import InlineFormRenderer
class HtmxMixin: class HtmxMixin:
""" """
Form mixin that retains only a single field when specified. Form mixin that retains only a single field when specified.
Useful when sending single fields with htmx. Useful when sending single fields with htmx.
""" """
default_renderer = InlineFormRenderer
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.single_field = kwargs.pop("single_field", None) self.single_field = kwargs.pop("single_field", None)

View file

@ -12,68 +12,60 @@
</div> </div>
{% endblock %} {% endblock %}
{% partialdef user-email %} {% partialdef user-email %}
<tr> <td>
<th>{% translate "E-mail" %}</th> {{ request.user.email }}
<td>{{ request.user.email }}</td> <button class="btn btn-primary"
<td>
<button class="btn btn-sm btn-primary"
hx-get="{% url 'frontend:profile' %}?fragment=user-email-edit" hx-get="{% url 'frontend:profile' %}?fragment=user-email-edit"
hx-target="closest tr" hx-target="closest td"
hx-swap="outerHTML">{% translate "Edit" %}</button> hx-swap="outerHTML">{% translate "Edit" %}</button>
</td> </td>
</tr>
{% endpartialdef user-email %} {% endpartialdef user-email %}
{% partialdef user-company %} {% partialdef user-company %}
<tr> <td>
<th>{% translate "Company" %}</th> {{ request.user.company|default_if_none:"" }}
<td>{{ request.user.company|default_if_none:"" }}</td> <button class="btn btn-primary"
<td>
<button class="btn btn-sm btn-primary"
hx-get="{% url 'frontend:profile' %}?fragment=user-company-edit" hx-get="{% url 'frontend:profile' %}?fragment=user-company-edit"
hx-target="closest tr" hx-target="closest td"
hx-swap="outerHTML">{% translate "Edit" %}</button> hx-swap="outerHTML">{% translate "Edit" %}</button>
</td> </td>
</tr>
{% endpartialdef user-company %} {% endpartialdef user-company %}
{% partialdef user-email-edit %} {% partialdef user-email-edit %}
<tr> <td>
<th>{% translate "E-mail" %}</th> <form hx-target="closest td"
<td colspan="2">
<form hx-target="closest tr"
hx-swap="outerHTML" hx-swap="outerHTML"
hx-post="{{ request.url }}"> hx-post="{{ request.url }}">
{{ form.email }} <div class="d-flex align-items-baseline">
{{ form.email.as_field_group }}
<input type="hidden" name="hx-single-field" value="email"> <input type="hidden" name="hx-single-field" value="email">
<input type="hidden" name="fragment" value="user-email"> <input type="hidden" name="fragment" value="user-email">
<button type="submit" class="btn btn-primary">{% translate "Save" %}</button> <button type="submit" class="btn btn-primary mx-1">{% translate "Save" %}</button>
<button type="button" <button type="button"
class="btn btn-secondary" class="btn btn-secondary"
hx-get="{{ request.path }}?fragment=user-email" hx-get="{{ request.path }}?fragment=user-email"
hx-target="closest tr" hx-target="closest td"
hx-swap="outerHTML">{% translate "Cancel" %}</button> hx-swap="outerHTML">{% translate "Cancel" %}</button>
</div>
</form> </form>
</td> </td>
</tr>
{% endpartialdef %} {% endpartialdef %}
{% partialdef user-company-edit %} {% partialdef user-company-edit %}
<tr> <td>
<th>{% translate "Company" %}</th> <form hx-target="closest td"
<td colspan="2">
<form hx-target="closest tr"
hx-swap="outerHTML" hx-swap="outerHTML"
hx-post="{{ request.url }}"> hx-post="{{ request.url }}">
{{ form.company }} <div class="d-flex align-items-baseline">
{{ form.company.as_field_group }}
<input type="hidden" name="hx-single-field" value="company"> <input type="hidden" name="hx-single-field" value="company">
<input type="hidden" name="fragment" value="user-company"> <input type="hidden" name="fragment" value="user-company">
<button type="submit" class="btn btn-primary">{% translate "Save" %}</button> <button type="submit" class="btn mx-1 btn-primary">{% translate "Save" %}</button>
<button type="button" <button type="button"
class="btn btn-secondary" class="btn btn-secondary"
hx-get="{{ request.path }}?fragment=user-company" hx-get="{{ request.path }}?fragment=user-company"
hx-target="closest tr" hx-target="closest td"
hx-swap="outerHTML">{% translate "Cancel" %}</button> hx-swap="outerHTML">{% translate "Cancel" %}</button>
</div>
</form> </form>
</td> </td>
</tr>
{% endpartialdef %} {% endpartialdef %}
{% block content %} {% block content %}
<section> <section>
@ -88,18 +80,18 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-lg"> <table class="table table-lg">
<tbody> <tbody>
<tr>
<th class="w-25">{% translate "Name" %}</th>
<td>{{ request.user.first_name }} {{ request.user.last_name }}</td>
</tr>
<tr>
<th class="w-25">{% translate "E-mail" %}</th>
{% partial user-email %} {% partial user-email %}
<tr>
<th>{% translate "First name" %}</th>
<td>{{ request.user.first_name }}</td>
<td></td>
</tr> </tr>
<tr> <tr>
<th>{% translate "Last name" %}</th> <th class="w-25">{% translate "Company" %}</th>
<td>{{ request.user.last_name }}</td>
<td></td>
</tr>
{% partial user-company %} {% partial user-company %}
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>