mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Introduce InlineFields for rendering fields side-by-side
This commit is contained in:
@ -16,6 +16,7 @@ from utilities.forms.fields import (
|
|||||||
CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField,
|
CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField,
|
||||||
NumericArrayField, SlugField,
|
NumericArrayField, SlugField,
|
||||||
)
|
)
|
||||||
|
from utilities.forms.rendering import InlineFields
|
||||||
from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK
|
from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK
|
||||||
from virtualization.models import Cluster
|
from virtualization.models import Cluster
|
||||||
from wireless.models import WirelessLAN, WirelessLANGroup
|
from wireless.models import WirelessLAN, WirelessLANGroup
|
||||||
@ -227,6 +228,22 @@ class RackForm(TenancyForm, NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
comments = CommentField()
|
comments = CommentField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
(_('Rack'), ('site', 'location', 'name', 'status', 'role', 'description', 'tags')),
|
||||||
|
(_('Inventory Control'), ('facility_id', 'serial', 'asset_tag')),
|
||||||
|
(_('Tenancy'), ('tenant_group', 'tenant')),
|
||||||
|
(_('Dimensions'), (
|
||||||
|
'type',
|
||||||
|
'width',
|
||||||
|
'starting_unit',
|
||||||
|
'u_height',
|
||||||
|
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
||||||
|
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
||||||
|
'mounting_depth',
|
||||||
|
'desc_units',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Rack
|
model = Rack
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -727,7 +727,6 @@ class RackNonRackedView(generic.ObjectChildrenView):
|
|||||||
class RackEditView(generic.ObjectEditView):
|
class RackEditView(generic.ObjectEditView):
|
||||||
queryset = Rack.objects.all()
|
queryset = Rack.objects.all()
|
||||||
form = forms.RackForm
|
form = forms.RackForm
|
||||||
template_name = 'dcim/rack_edit.html'
|
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(Rack, 'delete')
|
@register_model_view(Rack, 'delete')
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
{% extends 'generic/object_edit.html' %}
|
|
||||||
{% load form_helpers %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block form %}
|
|
||||||
<div class="field-group my-5">
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{% trans "Rack" %}</h5>
|
|
||||||
</div>
|
|
||||||
{% render_field form.site %}
|
|
||||||
{% render_field form.location %}
|
|
||||||
{% render_field form.name %}
|
|
||||||
{% render_field form.status %}
|
|
||||||
{% render_field form.role %}
|
|
||||||
{% render_field form.description %}
|
|
||||||
{% render_field form.tags %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-group my-5">
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{% trans "Inventory Control" %}</h5>
|
|
||||||
</div>
|
|
||||||
{% render_field form.facility_id %}
|
|
||||||
{% render_field form.serial %}
|
|
||||||
{% render_field form.asset_tag %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-group my-5">
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{% trans "Tenancy" %}</h5>
|
|
||||||
</div>
|
|
||||||
{% render_field form.tenant_group %}
|
|
||||||
{% render_field form.tenant %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-group my-5">
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{% trans "Dimensions" %}</h5>
|
|
||||||
</div>
|
|
||||||
{% render_field form.type %}
|
|
||||||
{% render_field form.width %}
|
|
||||||
{% render_field form.starting_unit %}
|
|
||||||
{% render_field form.u_height %}
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col col-md-3 col-form-label text-lg-end">{% trans "Outer Dimensions" %}</label>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.outer_width }}
|
|
||||||
<div class="form-text">{% trans "Width" %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.outer_depth }}
|
|
||||||
<div class="form-text">{% trans "Depth" %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.outer_unit }}
|
|
||||||
<div class="form-text">{% trans "Unit" %}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="col col-md-3 col-form-label text-lg-end">{% trans "Weight" %}</label>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.weight }}
|
|
||||||
<div class="form-text">{% trans "Weight" %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.max_weight }}
|
|
||||||
<div class="form-text">{% trans "Maximum Weight" %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-3 mb-1">
|
|
||||||
{{ form.weight_unit }}
|
|
||||||
<div class="form-text">{% trans "Unit" %}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% render_field form.mounting_depth %}
|
|
||||||
{% render_field form.desc_units %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if form.custom_fields %}
|
|
||||||
<div class="field-group my-5">
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
|
|
||||||
</div>
|
|
||||||
{% render_custom_fields form %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="field-group my-5">
|
|
||||||
{% render_field form.comments %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -9,21 +9,8 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{# Render grouped fields according to Form #}
|
{# Render grouped fields according to Form #}
|
||||||
{% for group, fields in form.fieldsets %}
|
{% for group, items in form.fieldsets %}
|
||||||
<div class="field-group mb-5">
|
{% render_fieldset form items heading=group %}
|
||||||
{% if group %}
|
|
||||||
<div class="row">
|
|
||||||
<h5 class="col-9 offset-3">{{ group }}</h5>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% for name in fields %}
|
|
||||||
{% with field=form|getfield:name %}
|
|
||||||
{% if field and not field.field.widget.is_hidden %}
|
|
||||||
{% render_field field %}
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if form.custom_fields %}
|
{% if form.custom_fields %}
|
||||||
|
10
netbox/utilities/forms/rendering.py
Normal file
10
netbox/utilities/forms/rendering.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
__all__ = (
|
||||||
|
'InlineFields',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class InlineFields:
|
||||||
|
|
||||||
|
def __init__(self, *field_names, label=None):
|
||||||
|
self.field_names = field_names
|
||||||
|
self.label = label
|
26
netbox/utilities/templates/form_helpers/render_fieldset.html
Normal file
26
netbox/utilities/templates/form_helpers/render_fieldset.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% load form_helpers %}
|
||||||
|
<div class="field-group mb-5">
|
||||||
|
{% if heading %}
|
||||||
|
<div class="row">
|
||||||
|
<h5 class="col-9 offset-3">{{ heading }}</h5>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% for layout, title, items in rows %}
|
||||||
|
{% if layout == 'field' %}
|
||||||
|
{# Single form field #}
|
||||||
|
{% render_field items.0 %}
|
||||||
|
{% elif layout == 'inline' %}
|
||||||
|
{# Multiple form fields on the same line #}
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col col-form-label text-lg-end">{{ title|default:'' }}</label>
|
||||||
|
{% for field in items %}
|
||||||
|
<div class="col mb-1">
|
||||||
|
{{ field }}
|
||||||
|
<div class="form-text">{% trans field.label %}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
@ -1,5 +1,7 @@
|
|||||||
from django import template
|
from django import template
|
||||||
|
|
||||||
|
from utilities.forms.rendering import InlineFields
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'getfield',
|
'getfield',
|
||||||
'render_custom_fields',
|
'render_custom_fields',
|
||||||
@ -45,6 +47,28 @@ def widget_type(field):
|
|||||||
# Inclusion tags
|
# Inclusion tags
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@register.inclusion_tag('form_helpers/render_fieldset.html')
|
||||||
|
def render_fieldset(form, fieldset, heading=None):
|
||||||
|
"""
|
||||||
|
Render a group set of fields.
|
||||||
|
"""
|
||||||
|
rows = []
|
||||||
|
for item in fieldset:
|
||||||
|
if type(item) is InlineFields:
|
||||||
|
rows.append(
|
||||||
|
('inline', item.label, [form[name] for name in item.field_names])
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
rows.append(
|
||||||
|
('field', None, [form[item]])
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'heading': heading,
|
||||||
|
'rows': rows,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@register.inclusion_tag('form_helpers/render_field.html')
|
@register.inclusion_tag('form_helpers/render_field.html')
|
||||||
def render_field(field, bulk_nullable=False, label=None):
|
def render_field(field, bulk_nullable=False, label=None):
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user