checktheroads 5 лет назад
Родитель
Сommit
3f1714f076

+ 9 - 0
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).

+ 7 - 12
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.

+ 31 - 0
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.