mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* Enable HTMX boosting * Refactor HTMX properties for tables * Fix dashboard object list widget * Disable scrolling to page content * Fix initialization of TomSelect dropdowns after HTMX loading * Replace formaction properties with hx-post * Fix quick search field on object list view * Reinitialize copy-to-clipboard buttons upon HTMX load * Disable scrolling effect for intra-page navigation * Introduce user preference for toggling HTMX navigation * Enable HTMX navigation only when selected by user * Pass htmx_navigation context * Fix display of confirmation form when deleting an object * Disable HTMX boosting for rack elevation SVG downloads * Fix dyanmic form rendering * Introduce htmx_boost template tag; enable HTMX for user menu * Use out-of-band sap to update footer stamp * Fix display of toasts after form submission * Fix user preference selection * Misc cleanup * Rename render_partial() to htmx_partial() * Add docstring to htmx_boost template tag * Disable HTMX for user preferences form to force a full page refresh on changes
This commit is contained in:
13
netbox/utilities/htmx.py
Normal file
13
netbox/utilities/htmx.py
Normal file
@@ -0,0 +1,13 @@
|
||||
__all__ = (
|
||||
'htmx_partial',
|
||||
)
|
||||
|
||||
PAGE_CONTAINER_ID = 'page-content'
|
||||
|
||||
|
||||
def htmx_partial(request):
|
||||
"""
|
||||
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
|
||||
@@ -1,4 +1,5 @@
|
||||
<div class="card-body htmx-container table-responsive p-0"
|
||||
hx-get="{% url viewname %}{% if url_params %}?{{ url_params.urlencode }}{% endif %}"
|
||||
hx-trigger="load"
|
||||
hx-target="this"
|
||||
hx-trigger="load" hx-select="table" hx-swap="innerHTML"
|
||||
></div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% if url %}
|
||||
<button type="submit" name="_delete" formaction="{{ url }}" class="btn btn-red">
|
||||
<button type="submit" name="_delete" {% formaction %}="{{ url }}" class="btn btn-red">
|
||||
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> {% trans "Delete Selected" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% if url %}
|
||||
<button type="submit" name="_edit" formaction="{{ url }}" class="btn btn-yellow">
|
||||
<button type="submit" name="_edit" {% formaction %}="{{ url }}" class="btn btn-yellow">
|
||||
<i class="mdi mdi-pencil" aria-hidden="true"></i> {% trans "Edit Selected" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<a href="#"
|
||||
hx-get="{{ url }}"
|
||||
hx-target="#htmx-modal-content"
|
||||
hx-swap="innerHTML"
|
||||
hx-select="form"
|
||||
class="btn btn-red"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#htmx-modal"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% load helpers %}
|
||||
{% load navigation %}
|
||||
|
||||
<ul class="navbar-nav pt-lg-2">
|
||||
<ul class="navbar-nav pt-lg-2" {% htmx_boost %}>
|
||||
{% for menu, groups in nav_items %}
|
||||
<li class="nav-item dropdown">
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ __all__ = (
|
||||
'checkmark',
|
||||
'copy_content',
|
||||
'customfield_value',
|
||||
'formaction',
|
||||
'tag',
|
||||
)
|
||||
|
||||
@@ -113,3 +114,14 @@ def htmx_table(context, viewname, return_url=None, **kwargs):
|
||||
'viewname': viewname,
|
||||
'url_params': url_params,
|
||||
}
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def formaction(context):
|
||||
"""
|
||||
Replace the 'formaction' attribute on an HTML element with the appropriate HTMX attributes
|
||||
if HTMX navigation is enabled (per the user's preferences).
|
||||
"""
|
||||
if context.get('htmx_navigation', False):
|
||||
return 'hx-push-url="true" hx-post'
|
||||
return 'formaction'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from typing import Dict
|
||||
from django import template
|
||||
from django.template import Context
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from netbox.navigation.menu import MENUS
|
||||
|
||||
__all__ = (
|
||||
'nav',
|
||||
'htmx_boost',
|
||||
)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ register = template.Library()
|
||||
|
||||
|
||||
@register.inclusion_tag("navigation/menu.html", takes_context=True)
|
||||
def nav(context: Context) -> Dict:
|
||||
def nav(context):
|
||||
"""
|
||||
Render the navigation menu.
|
||||
"""
|
||||
@@ -40,6 +40,31 @@ def nav(context: Context) -> Dict:
|
||||
nav_items.append((menu, groups))
|
||||
|
||||
return {
|
||||
"nav_items": nav_items,
|
||||
"request": context["request"]
|
||||
'nav_items': nav_items,
|
||||
'htmx_navigation': context['htmx_navigation']
|
||||
}
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def htmx_boost(context, target='#page-content', select='#page-content'):
|
||||
"""
|
||||
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 ''
|
||||
hx_params = {
|
||||
'hx-boost': 'true',
|
||||
'hx-target': target,
|
||||
'hx-select': select,
|
||||
'hx-swap': 'outerHTML show:window:top',
|
||||
}
|
||||
htmx_params = ' '.join([
|
||||
f'{k}="{v}"' for k, v in hx_params.items()
|
||||
])
|
||||
return mark_safe(htmx_params)
|
||||
|
||||
Reference in New Issue
Block a user