sparnatural
Version:
Visual client-side SPARQL query builder and knowledge graph exploration tool
109 lines • 5.1 kB
JavaScript
import { DataFactory } from 'rdf-data-factory';
import { AbstractWidget, RdfTermValue, ValueRepetition } from "./AbstractWidget";
import Awesomplete from 'awesomplete';
import { I18n } from '../../settings/I18n';
import { NoOpAutocompleteProvider } from '../datasources/NoOpDataProviders';
import { mergeDatasourceResults } from '../datasources/SparqlDataProviders';
const factory = new DataFactory();
export class AutoCompleteWidget extends AbstractWidget {
constructor(parentComponent, configuration, startClassValue, objectPropVal, endClassValue) {
super("autocomplete-widget", parentComponent, null, startClassValue, objectPropVal, endClassValue, ValueRepetition.MULTIPLE);
this.configuration = configuration;
}
render() {
super.render();
let inputHtml = $(`<input class="awesomplete"/>`);
this.html.append(inputHtml);
let errorHtml = $(`<div class="no-items" style="display: none; font-style:italic;">
${I18n.labels.ListWidgetNoItem}
</div>`);
// $( "#foo" )[ 0 ] is pulling the DOM element from the JQuery object
// see https://learn.jquery.com/using-jquery-core/faq/how-do-i-pull-a-native-dom-element-from-a-jquery-object/
const queryInput = inputHtml[0];
const awesomplete = new Awesomplete(queryInput, {
filter: () => {
return true;
},
sort: false,
minChars: 3,
maxItems: this.configuration.maxItems,
list: []
});
// the callback called when proposals have been fetched, to populate the suggestion list
let callback = (items) => {
// find distinct values of the 'group' binding
const groups = [...new Set(items.map(item => item.group))];
let list = new Array();
if (groups.length == 1 && groups[0] == undefined) {
// no groups defined at all
items.forEach(item => {
// Awesomplete list will contain the label as 'label', and the RDFTerm JSON serialization as 'value'
list.push({
label: item.label,
value: JSON.stringify(item.term)
});
});
}
else {
// we have some groups, merge
let mergedResult = mergeDatasourceResults(items);
mergedResult.forEach(item => {
list.push({
label: (item.group) ? "<span title='" + item.group + "'>" + item.label + "</span>" : item.label,
value: JSON.stringify(item.term)
});
});
}
// toggle spinner
if (list.length == 0) {
this.toggleSpinner(I18n.labels.AutocompleteSpinner_NoResults);
}
else {
this.toggleSpinner('');
}
// build final list
awesomplete.list = list;
awesomplete.evaluate();
};
let errorCallback = (payload) => {
this.toggleSpinner(I18n.labels.AutocompleteSpinner_NoResults);
};
// when user selects a value from the autocompletion list...
queryInput.addEventListener("awesomplete-selectcomplete", (event) => {
// fetch the autocomplete event payload, which is the JSON serialization of the RDFTerm
let awesompleteEvent = event.text;
let autocompleteValue = new RdfTermValue({
label: awesompleteEvent.label,
// parse back the RDFTerm as an object
rdfTerm: JSON.parse(awesompleteEvent.value),
});
// set the value on the criteria
inputHtml.val(autocompleteValue.value.label);
this.triggerRenderWidgetVal(autocompleteValue);
});
// add the behavior on the input HTML element to fetch the autocompletion value
var autocompleteTimer = 0;
queryInput.addEventListener("input", (event) => {
const phrase = event.target?.value;
// Process inputText as you want, e.g. make an API request.
if (phrase.length >= 3) {
// cancel the previously-set timer
if (autocompleteTimer) {
window.clearTimeout(autocompleteTimer);
}
autocompleteTimer = window.setTimeout(() => {
this.toggleSpinner(I18n.labels.AutocompleteSpinner_Searching);
this.configuration.dataProvider.getAutocompleteSuggestions(this.startClassVal.type, this.objectPropVal.type, this.endClassVal.type, phrase, callback, errorCallback);
}, 350);
}
});
return this;
}
parseInput(input) { return new RdfTermValue(input); }
}
// The default implementation of AutocompleteConfiguration
AutoCompleteWidget.defaultConfiguration = {
dataProvider: new NoOpAutocompleteProvider(),
maxItems: 15
};
//# sourceMappingURL=AutoCompleteWidget.js.map