diff --git a/src/frontend/components/form-group/filter/_filter.scss b/src/frontend/components/form-group/filter/_filter.scss new file mode 100644 index 000000000..2e7318d03 --- /dev/null +++ b/src/frontend/components/form-group/filter/_filter.scss @@ -0,0 +1,31 @@ +.rule-value-container { + .tt__container { + .twitter-typeahead { + .tt-menu { + max-height: 6em; + overflow-y: auto; + } + } + } +} + +.filter { + .rules-group-container { + .rules-group-body { + .rules-list { + .rule-container { + .rule-value-container { + .tt__container { + .twitter-typeahead { + .tt-menu { + max-height: 12em; + overflow-y: auto; + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/frontend/components/form-group/filter/lib/component.js b/src/frontend/components/form-group/filter/lib/component.js index ed839edbe..b4c448939 100644 --- a/src/frontend/components/form-group/filter/lib/component.js +++ b/src/frontend/components/form-group/filter/lib/component.js @@ -172,6 +172,7 @@ class FilterComponent extends Component { .withDataBuilder(buildQuery) .withDefaultMapper() .withName('rule') + .withAppendQuery() .withCallback(filterCallback) .build() }) @@ -198,7 +199,7 @@ class FilterComponent extends Component { if (devEndpoint) { return devEndpoint } else { - return `/${layoutId}/match/layout/${urlSuffix}` + return `/${layoutId}/match/layout/${urlSuffix}?q=` } } diff --git a/src/frontend/components/typeahead/_typeahead.scss b/src/frontend/components/typeahead/_typeahead.scss index 15d7dfc82..f3afef4ac 100644 --- a/src/frontend/components/typeahead/_typeahead.scss +++ b/src/frontend/components/typeahead/_typeahead.scss @@ -11,6 +11,8 @@ text-align: left; background-color: $white; background-clip: padding-box; + max-height: 15em; + overflow-y: auto; .tt-suggestion, .tt-dataset div { diff --git a/src/frontend/css/stylesheets/general.scss b/src/frontend/css/stylesheets/general.scss index 0c47d1379..30f77ff56 100644 --- a/src/frontend/css/stylesheets/general.scss +++ b/src/frontend/css/stylesheets/general.scss @@ -44,6 +44,7 @@ @import 'form-group/date-range/date-range'; @import 'form-group/query-builder/query-builder'; @import 'form-group/fieldset'; +@import 'form-group/filter/filter'; @import 'form-group/form-group'; @import 'form-group/input/input'; @import 'form-group/input/datepicker'; diff --git a/src/frontend/js/lib/util/typeahead/lib/Typeahead.ts b/src/frontend/js/lib/util/typeahead/lib/Typeahead.ts index 39261ea0d..82b7b78ee 100644 --- a/src/frontend/js/lib/util/typeahead/lib/Typeahead.ts +++ b/src/frontend/js/lib/util/typeahead/lib/Typeahead.ts @@ -1,6 +1,7 @@ import "typeahead.js"; -import { MappedResponse } from "util/mapper/mapper"; +import Bloodhound from "typeahead.js/dist/bloodhound"; import { TypeaheadSourceOptions } from "./TypeaheadSourceOptions"; +import { MappedResponse } from "util/mapper/mapper"; /** * Typeahead class for creating a typeahead @@ -9,10 +10,6 @@ import { TypeaheadSourceOptions } from "./TypeaheadSourceOptions"; * @param sourceOptions - options for the typeahead data source */ export class Typeahead { - private debug = false; - private timeout = null; - ajaxRequest: JQuery.jqXHR; - /** * Create a new Typeahead class * @param $input The input element to attach typeahead to @@ -28,42 +25,32 @@ export class Typeahead { */ private init() { const { appendQuery, mapper, name, ajaxSource } = this.sourceOptions; + const bloodhound = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.whitespace, + queryTokenizer: Bloodhound.tokenizers.whitespace, + remote: { + url: ajaxSource + (appendQuery ? "%QUERY" : ""), + wildcard: '%QUERY', + transform: (response) => { + return mapper(response); + }, + rateLimitBy: 'debounce', + rateLimitWait: 300, + cache: false, + } + }); + this.$input.typeahead({ - hint: true, - highlight: true, - minLength: 1 + hint: false, + highlight: false, + minLength: 0 }, { name: name, - source: (query, syncResults, asyncResults) => { - if (this.timeout) clearTimeout(this.timeout); - this.timeout = setTimeout(() => { - const request: JQuery.AjaxSettings = { - url: ajaxSource + (appendQuery ? query : ""), - dataType: "json", - beforeSend: () => { - this.ajaxRequest && this.ajaxRequest.abort(); - }, - success: (data) => { - if (this.debug) console.log("Typeahead data:", data); - const mapped = mapper(data); - if (this.debug) console.log("Typeahead mapped data:", mapped); - const filtered = mapped.filter((item: MappedResponse) => { - return item.name.toLowerCase().indexOf(query.toLowerCase()) !== -1; - }); - if (this.debug) console.log("Typeahead filtered data:", filtered); - asyncResults(filtered); - } - }; - if (this.sourceOptions.data) request.data = this.sourceOptions.data; - if (this.sourceOptions.dataBuilder) request.data = this.sourceOptions.dataBuilder(); - if (this.debug) console.log("Typeahead request: ", request); - this.ajaxRequest = $.ajax(request); - }, 200); - }, + source: bloodhound, display: 'name', - limit: 10, + limit: 20, templates: { - suggestion: (item: { name: String, id: number }) => { + suggestion: (item: MappedResponse) => { return `
${item.name}
`; }, pending: () => { @@ -78,5 +65,19 @@ export class Typeahead { this.$input.on('typeahead:select', (ev: any, suggestion: MappedResponse) => { this.callback(suggestion); }); + + if(window.test) { + this.$input.on("typeahead:asyncrequest", () => { + console.log("Typeahead async request"); + }); + + this.$input.on("typeahead:asyncreceive", () => { + console.log("Typeahead async receive"); + }); + + this.$input.on("typeahead:asynccancel", () => { + console.log("Typeahead async cancel"); + }); + } } };