mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-17 06:29:53 +02:00
* Fixes #20551: Support quick-add form prefix in automatic slug generation The slug generation logic in `reslug.ts` looks for form fields using hard-coded ID selectors like `#id_slug` and `#id_name`. In quick-add modals, Django applies a `quickadd` prefix to form fields (introduced in #20542), resulting in IDs like `#id_quickadd-slug` and `#id_quickadd-name`. The logic couldn't find these prefixed fields, so automatic slug generation failed silently in quick-add modals. This fix updates the field selectors to try both unprefixed and prefixed patterns using the nullish coalescing operator (`??`), checking for the standard field ID first and falling back to the quickadd-prefixed ID if the standard one isn't found. * Address PR feedback The slug generation logic required updates to support form prefixes like `quickadd`. Python-side changes ensure `SlugField.get_bound_field()` updates the `slug-source` attribute to include the form prefix when present, so JavaScript receives the correct prefixed field ID. `SlugWidget.__init__()` now adds a `slug-field` class to enable selector-based field discovery. On the frontend, `reslug.ts` now uses class selectors (`button.reslug` and `input.slug-field`) instead of ID-based lookups, eliminating the need for fallback logic. The template was updated to use `class="reslug"` instead of `id="reslug"` on the button to avoid ID duplication issues.
73 lines
2.6 KiB
HTML
73 lines
2.6 KiB
HTML
{% load form_helpers %}
|
|
{% load helpers %}
|
|
{% load i18n %}
|
|
|
|
<div class="row mb-3{% if field.errors %} has-errors{% endif %}">
|
|
|
|
{# Render the field label (if any), except for checkboxes #}
|
|
{% if label and not field|widget_type == 'checkboxinput' %}
|
|
<div class="col-sm-3 text-lg-end">
|
|
<label for="{{ field.id_for_label }}" class="col-form-label d-inline-block{% if field.field.required %} required{% endif %}">
|
|
{{ label }}
|
|
</label>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# Render the field itself #}
|
|
<div class="col{% if field|widget_type == 'checkboxinput' %} offset-3{% endif %}">
|
|
{# Include the "regenerate" button on slug fields #}
|
|
{% if field|widget_type == 'slugwidget' %}
|
|
<div class="input-group">
|
|
{{ field }}
|
|
<button type="button" title="{% trans "Regenerate Slug" %}" class="btn reslug">
|
|
<i class="mdi mdi-reload"></i>
|
|
</button>
|
|
</div>
|
|
{# Render checkbox labels to the right of the field #}
|
|
{% elif field|widget_type == 'checkboxinput' %}
|
|
<div class="form-check mb-0">
|
|
{{ field }}
|
|
<label for="{{ field.id_for_label }}" class="form-check-label">
|
|
{{ label }}
|
|
</label>
|
|
{% if field.help_text %}
|
|
<span class="form-text">{{ field.help_text|safe }}</span>
|
|
{% endif %}
|
|
</div>
|
|
{# Include a copy-to-clipboard button #}
|
|
{% elif 'data-clipboard' in field.field.widget.attrs %}
|
|
<div class="input-group">
|
|
{{ field }}
|
|
<button type="button" title="{% trans "Copy to clipboard" %}" class="btn copy-content" data-clipboard-target="#{{ field.id_for_label }}">
|
|
<i class="mdi mdi-content-copy"></i>
|
|
</button>
|
|
</div>
|
|
{# Default field rendering #}
|
|
{% else %}
|
|
{{ field }}
|
|
{% endif %}
|
|
|
|
{# Display any error messages #}
|
|
{% if field.errors %}
|
|
<div class="form-text text-danger">
|
|
{% for error in field.errors %}{{ error }}{% if not forloop.last %}<br />{% endif %}{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{# Help text #}
|
|
{% if field.help_text and field|widget_type != 'checkboxinput' %}
|
|
<span class="form-text">{{ field.help_text|safe }}</span>
|
|
{% endif %}
|
|
|
|
{# For bulk edit forms, include an option to nullify the field #}
|
|
{% if bulk_nullable %}
|
|
<div class="form-check my-1">
|
|
<input type="checkbox" class="form-check-input" name="_nullify" value="{{ field.name }}" id="nullify_{{ field.id_for_label }}" />
|
|
<label for="nullify_{{ field.id_for_label }}" class="form-check-label">{% trans "Set Null" %}</label>
|
|
</div>
|
|
{% endif %}
|
|
|
|
</div>
|
|
|
|
</div>
|