diff --git a/docs/content-services/search-filter.component.md b/docs/content-services/search-filter.component.md index 4f8d9a161f..36fabc8ab6 100644 --- a/docs/content-services/search-filter.component.md +++ b/docs/content-services/search-filter.component.md @@ -123,6 +123,16 @@ results: } ``` +You can choose to filter facet field results using 'contains' instead of 'starts with', by using the `filterWithContains` boolean (default is `false`): + +```json +{ + "search": { + "filterWithContains": true + } +} +``` + You can also provide a set of queries that are always executed alongside the user-defined settings: diff --git a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts index 673a3153fd..464083aa32 100644 --- a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts +++ b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts @@ -40,7 +40,7 @@ describe('SearchFilterComponent', () => { const searchMock: any = { dataLoaded: new Subject() }; - translationMock.instant = (key) => `translated${key}`; + translationMock.instant = (key) => `${key}_translated`; component = new SearchFilterComponent(queryBuilder, searchMock, translationMock); component.ngOnInit(); }); @@ -217,6 +217,53 @@ describe('SearchFilterComponent', () => { expect(component.responseFacetFields.length).toEqual(2); }); + it('should filter response facet fields based on search filter config method', () => { + queryBuilder.config = { + categories: [], + facetFields: { fields: [ + { label: 'f1', field: 'f1' } + ]}, + facetQueries: { + queries: [] + }, + filterWithContains: false + }; + + const initialFields: any = [ + { label: 'f1', buckets: [ + { label: 'firstLabel', display: 'firstLabel', count: 5 }, + { label: 'secondLabel', display: 'secondLabel', count: 5 }, + { label: 'thirdLabel', display: 'thirdLabel', count: 5 } + ] + } + ]; + + const data = { + list: { + context: { + facetsFields: initialFields + } + } + }; + + component.onDataLoaded(data); + expect(component.responseFacetFields[0].buckets.visibleItems.length).toBe(3); + + component.responseFacetFields[0].buckets.filterText = 'f'; + expect(component.responseFacetFields[0].buckets.visibleItems.length).toBe(1); + expect(component.responseFacetFields[0].buckets.visibleItems[0].label).toEqual('firstLabel'); + + component.responseFacetFields[0].buckets.filterText = 'label'; + expect(component.responseFacetFields[0].buckets.visibleItems.length).toBe(0); + + // Set filter method to use contains and test again + queryBuilder.config.filterWithContains = true; + component.responseFacetFields[0].buckets.filterText = 'f'; + expect(component.responseFacetFields[0].buckets.visibleItems.length).toBe(1); + component.responseFacetFields[0].buckets.filterText = 'label'; + expect(component.responseFacetFields[0].buckets.visibleItems.length).toBe(3); + }); + it('should fetch facet fields from response payload and show the bucket values', () => { component.responseFacetFields = null; diff --git a/lib/content-services/search/components/search-filter/search-filter.component.ts b/lib/content-services/search/components/search-filter/search-filter.component.ts index 38eaf64252..d0e1263e1f 100644 --- a/lib/content-services/search/components/search-filter/search-filter.component.ts +++ b/lib/content-services/search/components/search-filter/search-filter.component.ts @@ -233,7 +233,7 @@ export class SearchFilterComponent implements OnInit, OnDestroy { if (bucket && bucketList.filterText) { const pattern = (bucketList.filterText || '').toLowerCase(); const label = (this.translationService.instant(bucket.display) || this.translationService.instant(bucket.label)).toLowerCase(); - return label.startsWith(pattern); + return this.queryBuilder.config.filterWithContains ? label.indexOf(pattern) !== -1 : label.startsWith(pattern); } return true; }; diff --git a/lib/content-services/search/search-configuration.interface.ts b/lib/content-services/search/search-configuration.interface.ts index 22ff951d5d..43bf4c5ae3 100644 --- a/lib/content-services/search/search-configuration.interface.ts +++ b/lib/content-services/search/search-configuration.interface.ts @@ -26,6 +26,7 @@ export interface SearchConfiguration { fields?: Array; categories: Array; filterQueries?: Array; + filterWithContains?: boolean; facetQueries?: { label?: string; pageSize?: number; diff --git a/lib/core/app-config/schema.json b/lib/core/app-config/schema.json index 9100a767be..fbc0d3c8d4 100644 --- a/lib/core/app-config/schema.json +++ b/lib/core/app-config/schema.json @@ -905,6 +905,9 @@ } } }, + "filterWithContains": { + "type": "boolean" + }, "facetFields": { "type": "object", "required": [