From 3f1714f076b2d0ffe4a3735f108d5f48e6754e6a Mon Sep 17 00:00:00 2001 From: checktheroads Date: Mon, 15 Mar 2021 07:49:32 -0700 Subject: [PATCH] fix select loading display --- netbox/project-static/select.scss | 9 +++++++ netbox/project-static/src/select/api.ts | 19 ++++++--------- netbox/project-static/src/select/util.ts | 31 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/netbox/project-static/select.scss b/netbox/project-static/select.scss index 2c0c3873f..c1ed01927 100644 --- a/netbox/project-static/select.scss +++ b/netbox/project-static/select.scss @@ -29,6 +29,15 @@ div.form-floating div.ss-main div.ss-multi-selected { border-color: $form-feedback-icon-valid-color; } + .ss-single-selected, + .ss-multi-selected { + &[disabled] { + color: $form-select-disabled-color; + background-color: $form-select-disabled-bg; + border-color: $form-select-disabled-border-color; + } + } + .ss-single-selected { span.ss-arrow { // Inherit the arrow color from the parent (see color selector). diff --git a/netbox/project-static/src/select/api.ts b/netbox/project-static/src/select/api.ts index 10c327551..1679d5064 100644 --- a/netbox/project-static/src/select/api.ts +++ b/netbox/project-static/src/select/api.ts @@ -2,7 +2,7 @@ import SlimSelect from 'slim-select'; import queryString from 'query-string'; import { getApiData, isApiError, getElements } from '../util'; import { createToast } from '../toast'; -import { setOptionStyles, getFilteredBy } from './util'; +import { setOptionStyles, getFilteredBy, toggle } from './util'; import type { Option } from 'slim-select/dist/data'; @@ -155,7 +155,7 @@ export function initApiSelect() { }); // Disable the element while data has not been loaded. - instance.disable(); + toggle('disable', instance); // Don't copy classes from select element to SlimSelect instance. for (const className of select.classList) { @@ -166,13 +166,12 @@ export function initApiSelect() { getChoices(url, displayField, selectOptions, disabledOptions) .then(options => instance.setData(options)) .finally(() => { + // Set option styles, if the field calls for it (color selectors). + setOptionStyles(instance); // Inform any event listeners that data has updated. select.dispatchEvent(event); // Enable the element after data has loaded. - instance.enable(); - // Set option styles, if the field calls for it (color selectors). Note: this must be - // done after instance.enable() since instance.enable() changes the element style. - setOptionStyles(instance); + toggle('enable', instance); }); // Reset validity classes if the field was invalid. @@ -253,17 +252,13 @@ export function initApiSelect() { } // Disable the element while data is loading. - instance.disable(); + toggle('disable', instance); // Load new data. getChoices(filterUrl, displayField, selectOptions, disabledOptions) .then(data => instance.setData(data)) .finally(() => { // Re-enable the element after data has loaded. - instance.enable(); - // Set option styles, if the field calls for it (color selectors). Note: this must - // be done after instance.enable() since instance.enable() changes the element - // style. - setOptionStyles(instance); + toggle('enable', instance); }); } // Re-fetch data when the group changes. diff --git a/netbox/project-static/src/select/util.ts b/netbox/project-static/src/select/util.ts index 001131c11..7acd6ab72 100644 --- a/netbox/project-static/src/select/util.ts +++ b/netbox/project-static/src/select/util.ts @@ -2,6 +2,36 @@ import { readableColor } from 'color2k'; import type SlimSelect from 'slim-select'; +/** + * Add or remove a class to the SlimSelect element to match Bootstrap .form-select:disabled styles. + * + * @param action `enable` or `disable` + * @param instance Instance of SlimSelect + */ +export function toggle(action: 'enable' | 'disable', instance: SlimSelect): void { + if (action === 'enable') { + if (instance.slim.singleSelected !== null) { + if (instance.slim.singleSelected.container.hasAttribute('disabled')) { + instance.slim.singleSelected.container.removeAttribute('disabled'); + } + } else if (instance.slim.multiSelected !== null) { + if (instance.slim.multiSelected.container.hasAttribute('disabled')) { + instance.slim.multiSelected.container.removeAttribute('disabled'); + } + } + } else if (action === 'disable') { + if (instance.slim.singleSelected !== null) { + if (!instance.slim.singleSelected.container.hasAttribute('disabled')) { + instance.slim.singleSelected.container.setAttribute('disabled', ''); + } + } else if (instance.slim.multiSelected !== null) { + if (!instance.slim.multiSelected.container.hasAttribute('disabled')) { + instance.slim.multiSelected.container.setAttribute('disabled', ''); + } + } + } +} + /** * Add scoped style elements specific to each SlimSelect option, if the color property exists. * As of this writing, this attribute only exist on Tags. The color property is used as the @@ -11,6 +41,7 @@ import type SlimSelect from 'slim-select'; * @param instance SlimSelect instance with options already set. */ export function setOptionStyles(instance: SlimSelect): void { + console.log('1', instance); const options = instance.data.data; for (const option of options) { // Only create style elements for options that contain a color attribute.