1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

#7123: Handle empty_option on API Select

This commit is contained in:
thatmattlove
2021-09-01 17:02:43 -07:00
parent 774dff07ee
commit ddff193786
4 changed files with 34 additions and 25 deletions

View File

@ -22,13 +22,6 @@ import type { Stringifiable } from 'query-string';
import type { Option } from 'slim-select/dist/data';
import type { Trigger, PathFilter, ApplyMethod, QueryFilter } from './types';
// Empty placeholder option.
const PLACEHOLDER = {
value: '',
text: '',
placeholder: true,
} as Option;
// Attributes which if truthy should render the option disabled.
const DISABLED_ATTRIBUTES = ['occupied'] as string[];
@ -52,6 +45,8 @@ export class APISelect {
*/
public readonly placeholder: string;
public readonly emptyOption: Nullable<Option> = null;
/**
* Event that will initiate the API call to NetBox to load option data. By default, the trigger
* is `'load'`, so data will be fetched when the element renders on the page.
@ -147,7 +142,7 @@ export class APISelect {
/**
* This instance's available options.
*/
private _options: Option[] = [PLACEHOLDER];
private _options: Option[] = [];
/**
* Array of options values which should be considered disabled or static.
@ -168,6 +163,14 @@ export class APISelect {
this.preSorted = true;
}
const emptyOption = base.getAttribute('data-empty-option');
if (isTruthy(emptyOption)) {
this.emptyOption = {
text: emptyOption,
value: '',
};
}
if (hasUrl(base)) {
const url = base.getAttribute('data-url') as string;
this.url = url;
@ -285,17 +288,16 @@ export class APISelect {
// Get the placeholder index (note: if there is no placeholder, the index will be `-1`).
const placeholderIdx = deduplicated.findIndex(o => o.value === '');
if (hasPlaceholder && placeholderIdx < 0) {
if (hasPlaceholder && placeholderIdx < 0 && this.emptyOption !== null) {
// If there is a placeholder but it is not the first element (due to sorting or other merge
// issues), remove it from the options array and place it in front.
deduplicated.splice(placeholderIdx);
deduplicated = [PLACEHOLDER, ...deduplicated];
deduplicated = [this.emptyOption, ...deduplicated];
}
if (!hasPlaceholder) {
if (!hasPlaceholder && this.emptyOption !== null) {
// If there is no placeholder, add one to the front of the array.
deduplicated = [PLACEHOLDER, ...deduplicated];
deduplicated = [this.emptyOption, ...deduplicated];
}
this._options = deduplicated;
this.slim.setData(deduplicated);
}
@ -304,7 +306,11 @@ export class APISelect {
* Remove all options and reset back to the generic placeholder.
*/
private resetOptions(): void {
this.options = [PLACEHOLDER];
if (this.emptyOption !== null) {
this.options = [this.emptyOption];
} else {
this.options = [];
}
}
/**
@ -534,7 +540,7 @@ export class APISelect {
*/
private async getOptions(action: ApplyMethod = 'merge'): Promise<void> {
if (this.queryUrl.includes(`{{`)) {
this.options = [PLACEHOLDER];
this.resetOptions();
return;
}
await this.fetchOptions(this.queryUrl, action);