Compare commits

...

3 Commits

Author SHA1 Message Date
Jeremy Stretch c7a63e02f2 Disable HTMX for user preferences form to force a full page refresh on changes 2024-03-27 12:11:24 -04:00
Jeremy Stretch 41f21d31ef Add docstring to htmx_boost template tag 2024-03-27 09:30:11 -04:00
Jeremy Stretch 6c540e56ff Rename render_partial() to htmx_partial() 2024-03-27 09:24:39 -04:00
8 changed files with 28 additions and 18 deletions

View File

@ -25,7 +25,7 @@ from netbox.views import generic
from netbox.views.generic.base import BaseObjectView from netbox.views.generic.base import BaseObjectView
from netbox.views.generic.mixins import TableMixin from netbox.views.generic.mixins import TableMixin
from utilities.forms import ConfirmationForm from utilities.forms import ConfirmationForm
from utilities.htmx import render_partial from utilities.htmx import htmx_partial
from utilities.query import count_related from utilities.query import count_related
from utilities.views import ContentTypePermissionRequiredMixin, register_model_view from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
from . import filtersets, forms, tables from . import filtersets, forms, tables
@ -321,7 +321,7 @@ class BackgroundTaskListView(TableMixin, BaseRQView):
table = self.get_table(data, request, False) table = self.get_table(data, request, False)
# If this is an HTMX request, return only the rendered table HTML # If this is an HTMX request, return only the rendered table HTML
if render_partial(request): if htmx_partial(request):
return render(request, 'htmx/table.html', { return render(request, 'htmx/table.html', {
'table': table, 'table': table,
}) })
@ -490,7 +490,7 @@ class WorkerListView(TableMixin, BaseRQView):
table = self.get_table(data, request, False) table = self.get_table(data, request, False)
# If this is an HTMX request, return only the rendered table HTML # If this is an HTMX request, return only the rendered table HTML
if render_partial(request): if htmx_partial(request):
if not request.htmx.target: if not request.htmx.target:
table.embedded = True table.embedded = True
# Hide selection checkboxes # Hide selection checkboxes

View File

@ -20,7 +20,7 @@ from netbox.views import generic
from netbox.views.generic.mixins import TableMixin from netbox.views.generic.mixins import TableMixin
from utilities.data import shallow_compare_dict from utilities.data import shallow_compare_dict
from utilities.forms import ConfirmationForm, get_field_value from utilities.forms import ConfirmationForm, get_field_value
from utilities.htmx import render_partial from utilities.htmx import htmx_partial
from utilities.paginator import EnhancedPaginator, get_paginate_count from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.query import count_related from utilities.query import count_related
from utilities.querydict import normalize_querydict from utilities.querydict import normalize_querydict
@ -1225,7 +1225,7 @@ class ScriptResultView(TableMixin, generic.ObjectView):
} }
# If this is an HTMX request, return only the result HTML # If this is an HTMX request, return only the result HTML
if render_partial(request): if htmx_partial(request):
response = render(request, 'extras/htmx/script_result.html', context) response = render(request, 'extras/htmx/script_result.html', context)
if job.completed or not job.started: if job.completed or not job.started:
response.status_code = 286 response.status_code = 286

View File

@ -23,7 +23,7 @@ from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
from utilities.forms.bulk_import import BulkImportForm from utilities.forms.bulk_import import BulkImportForm
from utilities.htmx import render_partial from utilities.htmx import htmx_partial
from utilities.permissions import get_permission_for_model from utilities.permissions import get_permission_for_model
from utilities.views import GetReturnURLMixin, get_viewname from utilities.views import GetReturnURLMixin, get_viewname
from .base import BaseMultiObjectView from .base import BaseMultiObjectView
@ -162,7 +162,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
table = self.get_table(self.queryset, request, has_bulk_actions) table = self.get_table(self.queryset, request, has_bulk_actions)
# If this is an HTMX request, return only the rendered table HTML # If this is an HTMX request, return only the rendered table HTML
if render_partial(request): if htmx_partial(request):
if not request.htmx.target: if not request.htmx.target:
table.embedded = True table.embedded = True
# Hide selection checkboxes # Hide selection checkboxes

View File

@ -17,7 +17,7 @@ from extras.signals import clear_events
from utilities.error_handlers import handle_protectederror from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, PermissionsViolation from utilities.exceptions import AbortRequest, PermissionsViolation
from utilities.forms import ConfirmationForm, restrict_form_fields from utilities.forms import ConfirmationForm, restrict_form_fields
from utilities.htmx import render_partial from utilities.htmx import htmx_partial
from utilities.permissions import get_permission_for_model from utilities.permissions import get_permission_for_model
from utilities.querydict import normalize_querydict, prepare_cloned_fields from utilities.querydict import normalize_querydict, prepare_cloned_fields
from utilities.views import GetReturnURLMixin, get_viewname from utilities.views import GetReturnURLMixin, get_viewname
@ -139,7 +139,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
table = self.get_table(table_data, request, has_bulk_actions) table = self.get_table(table_data, request, has_bulk_actions)
# If this is an HTMX request, return only the rendered table HTML # If this is an HTMX request, return only the rendered table HTML
if render_partial(request): if htmx_partial(request):
return render(request, 'htmx/table.html', { return render(request, 'htmx/table.html', {
'object': instance, 'object': instance,
'table': table, 'table': table,
@ -227,7 +227,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView):
restrict_form_fields(form, request.user) restrict_form_fields(form, request.user)
# If this is an HTMX request, return only the rendered form HTML # If this is an HTMX request, return only the rendered form HTML
if render_partial(request): if htmx_partial(request):
return render(request, 'htmx/form.html', { return render(request, 'htmx/form.html', {
'form': form, 'form': form,
}) })
@ -483,7 +483,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
instance = self.alter_object(self.queryset.model(), request) instance = self.alter_object(self.queryset.model(), request)
# If this is an HTMX request, return only the rendered form HTML # If this is an HTMX request, return only the rendered form HTML
if render_partial(request): if htmx_partial(request):
return render(request, 'htmx/form.html', { return render(request, 'htmx/form.html', {
'form': form, 'form': form,
}) })

View File

@ -17,7 +17,7 @@ from netbox.forms import SearchForm
from netbox.search import LookupTypes from netbox.search import LookupTypes
from netbox.search.backends import search_backend from netbox.search.backends import search_backend
from netbox.tables import SearchTable from netbox.tables import SearchTable
from utilities.htmx import render_partial from utilities.htmx import htmx_partial
from utilities.paginator import EnhancedPaginator, get_paginate_count from utilities.paginator import EnhancedPaginator, get_paginate_count
__all__ = ( __all__ = (
@ -105,7 +105,7 @@ class SearchView(View):
}).configure(table) }).configure(table)
# If this is an HTMX request, return only the rendered table HTML # If this is an HTMX request, return only the rendered table HTML
if render_partial(request): if htmx_partial(request):
return render(request, 'htmx/table.html', { return render(request, 'htmx/table.html', {
'table': table, 'table': table,
}) })

View File

@ -6,7 +6,7 @@
{% block title %}{% trans "User Preferences" %}{% endblock %} {% block title %}{% trans "User Preferences" %}{% endblock %}
{% block content %} {% block content %}
<form method="post" action="" id="preferences-update"> <form method="post" action="" hx-disable="true" id="preferences-update">
{% csrf_token %} {% csrf_token %}
{# Built-in preferences #} {# Built-in preferences #}

View File

@ -1,12 +1,13 @@
__all__ = ( __all__ = (
'render_partial', 'htmx_partial',
) )
PAGE_CONTAINER_ID = 'page-content' PAGE_CONTAINER_ID = 'page-content'
def render_partial(request): def htmx_partial(request):
""" """
Determines whether to render a partial response. Determines whether to render partial (versus complete) HTML content
in response to an HTMX request, based on the target element.
""" """
return request.htmx and request.htmx.target != PAGE_CONTAINER_ID return request.htmx and request.htmx.target != PAGE_CONTAINER_ID

View File

@ -47,7 +47,16 @@ def nav(context):
@register.simple_tag(takes_context=True) @register.simple_tag(takes_context=True)
def htmx_boost(context, target='#page-content', select='#page-content'): def htmx_boost(context, target='#page-content', select='#page-content'):
if not context.get('htmx_navigation'): """
Renders the HTML attributes needed to effect HTMX boosting within an element if
HTMX navigation is enabled for the request. The target and select parameters are
rendered as `hx-target` and `hx-select`, respectively. For example:
<div id="page-content" {% htmx_boost %}>
If HTMX navigation is not enabled, the tag renders no content.
"""
if not context.get('htmx_navigation', False):
return '' return ''
hx_params = { hx_params = {
'hx-boost': 'true', 'hx-boost': 'true',