From 872b70c2b51a202772198e6d8e51d3bf3f98ad9c Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 3 Apr 2023 12:49:26 -0400 Subject: [PATCH] Fixes #12145: Employ HTMXSelect widget to fix inclusion of ` field values during form regeneration * [#12146](https://github.com/netbox-community/netbox/issues/12146) - Do not display object selector for disabled fields ### Other Changes diff --git a/netbox/core/forms/model_forms.py b/netbox/core/forms/model_forms.py index 99e2786ef..67732d5be 100644 --- a/netbox/core/forms/model_forms.py +++ b/netbox/core/forms/model_forms.py @@ -7,6 +7,7 @@ from extras.forms.mixins import SyncedDataMixin from netbox.forms import NetBoxModelForm from netbox.registry import registry from utilities.forms import CommentField, get_field_value +from utilities.forms.widgets import HTMXSelect __all__ = ( 'DataSourceForm', @@ -23,13 +24,7 @@ class DataSourceForm(NetBoxModelForm): 'name', 'type', 'source_url', 'enabled', 'description', 'comments', 'ignore_rules', 'tags', ] widgets = { - 'type': forms.Select( - attrs={ - 'hx-get': '.', - 'hx-include': '#form_fields input', - 'hx-target': '#form_fields', - } - ), + 'type': HTMXSelect(), 'ignore_rules': forms.Textarea( attrs={ 'rows': 5, diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index d5228d20a..6c8ca7566 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -12,10 +12,10 @@ from ipam.models import ASN, IPAddress, VLAN, VLANGroup, VRF from netbox.forms import NetBoxModelForm from tenancy.forms import TenancyForm from utilities.forms import ( - APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField, - DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK, - SlugField, SelectSpeedWidget + add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField, + DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SlugField, ) +from utilities.forms.widgets import APISelect, HTMXSelect, SelectSpeedWidget, SelectWithPK from virtualization.models import Cluster from wireless.models import WirelessLAN, WirelessLANGroup from .common import InterfaceCommonForm, ModuleCommonForm @@ -1136,13 +1136,7 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm): ] widgets = { 'speed': SelectSpeedWidget(), - 'mode': forms.Select( - attrs={ - 'hx-get': '.', - 'hx-include': '#form_fields input', - 'hx-target': '#form_fields', - } - ), + 'mode': HTMXSelect(), } labels = { 'mode': '802.1Q Mode', diff --git a/netbox/utilities/forms/widgets.py b/netbox/utilities/forms/widgets.py index 5e84533b0..7b20d00c9 100644 --- a/netbox/utilities/forms/widgets.py +++ b/netbox/utilities/forms/widgets.py @@ -16,6 +16,7 @@ __all__ = ( 'ColorSelect', 'DatePicker', 'DateTimePicker', + 'HTMXSelect', 'MarkdownWidget', 'NumericArrayField', 'SelectDurationWidget', @@ -293,3 +294,19 @@ class TimePicker(forms.TextInput): super().__init__(*args, **kwargs) self.attrs['class'] = 'time-picker' self.attrs['placeholder'] = 'hh:mm:ss' + + +class HTMXSelect(forms.Select): + """ + Selection widget that will re-generate the HTML form upon the selection of a new option. + """ + def __init__(self, hx_url='.', hx_target_id='form_fields', attrs=None, **kwargs): + _attrs = { + 'hx-get': hx_url, + 'hx-include': f'#{hx_target_id}', + 'hx-target': f'#{hx_target_id}', + } + if attrs: + _attrs.update(attrs) + + super().__init__(attrs=_attrs, **kwargs) diff --git a/netbox/virtualization/forms/model_forms.py b/netbox/virtualization/forms/model_forms.py index a807b4fd9..95a80e177 100644 --- a/netbox/virtualization/forms/model_forms.py +++ b/netbox/virtualization/forms/model_forms.py @@ -12,6 +12,7 @@ from utilities.forms import ( BootstrapMixin, CommentField, ConfirmationForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, SlugField, ) +from utilities.forms.widgets import HTMXSelect from virtualization.models import * __all__ = ( @@ -318,13 +319,7 @@ class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm): 'mode': '802.1Q Mode', } widgets = { - 'mode': forms.Select( - attrs={ - 'hx-get': '.', - 'hx-include': '#form_fields input', - 'hx-target': '#form_fields', - } - ), + 'mode': HTMXSelect(), } def __init__(self, *args, **kwargs):