diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 257907015..83cdff29e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1833,7 +1833,10 @@ class CableCreateForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm): label='Name', widget=APISelect( api_url='/api/dcim/{{termination_b_type}}s/?device_id={{termination_b_device}}', - disabled_indicator='cable' + disabled_indicator='cable', + url_conditional_append={ + 'termination_b_type__interface': '&type=physical', + } ) ) diff --git a/netbox/project-static/js/forms.js b/netbox/project-static/js/forms.js index 7ea4b152b..a494664c7 100644 --- a/netbox/project-static/js/forms.js +++ b/netbox/project-static/js/forms.js @@ -91,8 +91,9 @@ $(document).ready(function() { var filter_regex = /\{\{([a-z_]+)\}\}/g; var match; var rendered_url = api_url; + var filter_field; while (match = filter_regex.exec(api_url)) { - var filter_field = $('#id_' + match[1]); + filter_field = $('#id_' + match[1]); var custom_attr = $('option:selected', filter_field).attr('api-value'); if (custom_attr) { rendered_url = rendered_url.replace(match[0], custom_attr); @@ -103,6 +104,20 @@ $(document).ready(function() { } } + // Account for any conditional URL append strings + $.each(child_field[0].attributes, function(index, attr){ + if (attr.name.includes("data-url-conditional-append-")){ + var conditional = attr.name.split("data-url-conditional-append-")[1].split("__"); + var field = $("#id_" + conditional[0]); + var field_value = conditional[1]; + console.log($('option:selected', field).attr('api-value')); + if ($('option:selected', field).attr('api-value') === field_value){ + console.log(attr.value); + rendered_url = rendered_url + attr.value; + } + } + }) + // If all URL variables have been replaced, make the API call if (rendered_url.search('{{') < 0) { console.log(child_name + ": Fetching " + rendered_url); diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py index baa035aa7..51e553cf9 100644 --- a/netbox/utilities/forms.py +++ b/netbox/utilities/forms.py @@ -258,9 +258,21 @@ class APISelect(SelectWithDisabled): :param api_url: API URL :param display_field: (Optional) Field to display for child in selection list. Defaults to `name`. :param disabled_indicator: (Optional) Mark option as disabled if this field equates true. + :param url_conditional_append: (Optional) A dict of URL query strings to append to the URL if the + condition is met. The condition is the dict key and is specified in the form `__`. + If the provided field value is selected for the given field, the URL query string will be appended to + the rendered URL. This is useful in cases where a particular field value dictates an additional API filter. """ - def __init__(self, api_url, display_field=None, disabled_indicator=None, *args, **kwargs): + def __init__( + self, + api_url, + display_field=None, + disabled_indicator=None, + url_conditional_append=None, + *args, + **kwargs + ): super(APISelect, self).__init__(*args, **kwargs) @@ -270,6 +282,9 @@ class APISelect(SelectWithDisabled): self.attrs['display-field'] = display_field if disabled_indicator: self.attrs['disabled-indicator'] = disabled_indicator + if url_conditional_append: + for key, value in url_conditional_append.items(): + self.attrs["data-url-conditional-append-{}".format(key)] = value class APISelectMultiple(APISelect):