mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-17 21:18:16 -06:00
Initial work on #13283
This commit is contained in:
parent
d63e1dacbf
commit
ff460c2829
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
@ -31,6 +31,13 @@ export class DynamicTomSelect extends TomSelect {
|
|||||||
// Glean the REST API endpoint URL from the <select> element
|
// Glean the REST API endpoint URL from the <select> element
|
||||||
this.api_url = this.input.getAttribute('data-url') as string;
|
this.api_url = this.input.getAttribute('data-url') as string;
|
||||||
|
|
||||||
|
// Override any field names set as widget attributes
|
||||||
|
this.valueField = this.input.getAttribute('ts-value-field') || this.settings.valueField;
|
||||||
|
this.labelField = this.input.getAttribute('ts-label-field') || this.settings.labelField;
|
||||||
|
this.parentField = this.input.getAttribute('ts-parent-field') || null;
|
||||||
|
this.depthField = this.input.getAttribute('ts-depth-field') || '_depth';
|
||||||
|
this.descriptionField = this.input.getAttribute('ts-description-field') || 'description';
|
||||||
|
|
||||||
// Set the null option (if any)
|
// Set the null option (if any)
|
||||||
const nullOption = this.input.getAttribute('data-null-option');
|
const nullOption = this.input.getAttribute('data-null-option');
|
||||||
if (nullOption) {
|
if (nullOption) {
|
||||||
@ -82,8 +89,18 @@ export class DynamicTomSelect extends TomSelect {
|
|||||||
// Make the API request
|
// Make the API request
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(json => {
|
.then(apiData => {
|
||||||
self.loadCallback(json.results, []);
|
const results: Dict[] = apiData.results;
|
||||||
|
let options: Dict[] = []
|
||||||
|
for (let result of results) {
|
||||||
|
const option = self.getOptionFromData(result);
|
||||||
|
options.push(option);
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
})
|
||||||
|
// Pass the options to the callback function
|
||||||
|
.then(options => {
|
||||||
|
self.loadCallback(options, []);
|
||||||
}).catch(()=>{
|
}).catch(()=>{
|
||||||
self.loadCallback([], []);
|
self.loadCallback([], []);
|
||||||
});
|
});
|
||||||
@ -126,6 +143,21 @@ export class DynamicTomSelect extends TomSelect {
|
|||||||
return queryString.stringifyUrl({ url, query });
|
return queryString.stringifyUrl({ url, query });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compile TomOption data from an API result
|
||||||
|
getOptionFromData(data: Dict) {
|
||||||
|
let option: Dict = {
|
||||||
|
id: data[this.valueField],
|
||||||
|
display: data[this.labelField],
|
||||||
|
depth: data[this.depthField] || null,
|
||||||
|
description: data[this.descriptionField] || null,
|
||||||
|
};
|
||||||
|
if (data[this.parentField]) {
|
||||||
|
let parent: Dict = data[this.parentField] as Dict;
|
||||||
|
option['parent'] = parent[this.labelField];
|
||||||
|
}
|
||||||
|
return option
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitional methods
|
* Transitional methods
|
||||||
*/
|
*/
|
||||||
|
@ -10,12 +10,31 @@ const MAX_OPTIONS = 100;
|
|||||||
|
|
||||||
// Render the HTML for a dropdown option
|
// Render the HTML for a dropdown option
|
||||||
function renderOption(data: TomOption, escape: typeof escape_html) {
|
function renderOption(data: TomOption, escape: typeof escape_html) {
|
||||||
// If the option has a `_depth` property, indent its label
|
let html = '<div>';
|
||||||
if (typeof data._depth === 'number' && data._depth > 0) {
|
|
||||||
return `<div>${'─'.repeat(data._depth)} ${escape(data[LABEL_FIELD])}</div>`;
|
// If the option has a `depth` property, indent its label
|
||||||
|
if (typeof data.depth === 'number' && data.depth > 0) {
|
||||||
|
html = `${html}${'─'.repeat(data.depth)} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<div>${escape(data[LABEL_FIELD])}</div>`;
|
html = `${html}${escape(data[LABEL_FIELD])}`;
|
||||||
|
if (data['parent']) {
|
||||||
|
html = `${html} <span class="text-secondary">${escape(data['parent'])}</span>`;
|
||||||
|
}
|
||||||
|
if (data['description']) {
|
||||||
|
html = `${html}<br /><small class="text-secondary">${escape(data['description'])}</small>`;
|
||||||
|
}
|
||||||
|
html = `${html}</div>`;
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the HTML for a selected item
|
||||||
|
function renderItem(data: TomOption, escape: typeof escape_html) {
|
||||||
|
if (data['parent']) {
|
||||||
|
return `<div>${escape(data['parent'])} > ${escape(data[LABEL_FIELD])}</div>`;
|
||||||
|
}
|
||||||
|
return `<div>${escape(data[LABEL_FIELD])}<div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize <select> elements which are populated via a REST API call
|
// Initialize <select> elements which are populated via a REST API call
|
||||||
@ -40,6 +59,7 @@ export function initDynamicSelects(): void {
|
|||||||
// Define custom rendering functions
|
// Define custom rendering functions
|
||||||
render: {
|
render: {
|
||||||
option: renderOption,
|
option: renderOption,
|
||||||
|
item: renderItem,
|
||||||
},
|
},
|
||||||
|
|
||||||
// By default, load() will be called only if query.length > 0
|
// By default, load() will be called only if query.length > 0
|
||||||
|
Loading…
Reference in New Issue
Block a user