From 7dfb06f9e652dd550d04bd569134fa2cb6a87c76 Mon Sep 17 00:00:00 2001 From: Ghislain Beaulac Date: Wed, 23 May 2018 18:37:01 -0400 Subject: [PATCH] refactor(searchTerm): remove searchTerm and only use searchTerms - prior to this, user could predefined searchTerm (singular) or searchTerms (array). To simplify the logic, the singular searchTerm has been dropped in favor of the array searchTerms --- src/app/examples/custom-inputFilter.ts | 14 ++++--- src/app/examples/grid-clientside.component.ts | 6 +-- src/app/examples/grid-graphql.component.ts | 4 +- .../examples/grid-rowselection.component.ts | 2 +- src/app/examples/swt-common-grid.component.ts | 2 +- .../booleanFilterCondition.ts | 3 +- .../filter-conditions/dateFilterCondition.ts | 5 ++- .../dateIsoFilterCondition.ts | 5 ++- .../dateUsFilterCondition.ts | 5 ++- .../dateUsShortFilterCondition.ts | 5 ++- .../dateUtcFilterCondition.ts | 5 ++- .../numberFilterCondition.ts | 3 +- .../stringFilterCondition.ts | 3 +- .../filters/compoundDateFilter.ts | 37 ++++++++++--------- .../filters/compoundInputFilter.ts | 33 +++++++++-------- .../angular-slickgrid/filters/inputFilter.ts | 25 ++++++++----- .../filters/multipleSelectFilter.ts | 7 +++- .../angular-slickgrid/filters/selectFilter.ts | 13 ++++--- .../filters/singleSelectFilter.ts | 24 +++++++----- .../models/columnFilter.interface.ts | 3 -- .../models/currentFilter.interface.ts | 1 - .../models/filter.interface.ts | 3 -- .../models/filterArguments.interface.ts | 1 - .../models/filterCallback.interface.ts | 1 - .../models/filterChangedArgs.interface.ts | 1 - .../models/filterConditionOption.interface.ts | 1 - .../services/filter.service.ts | 33 +++-------------- .../services/graphql.service.ts | 6 +-- .../services/grid-odata.service.ts | 8 ++-- 29 files changed, 128 insertions(+), 131 deletions(-) diff --git a/src/app/examples/custom-inputFilter.ts b/src/app/examples/custom-inputFilter.ts index 341cc26f1..2a69ba3d9 100644 --- a/src/app/examples/custom-inputFilter.ts +++ b/src/app/examples/custom-inputFilter.ts @@ -6,7 +6,7 @@ declare var $: any; export class CustomInputFilter implements Filter { private $filterElm: any; grid: any; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; @@ -19,13 +19,17 @@ export class CustomInputFilter implements Filter { this.grid = args.grid; this.callback = args.callback; this.columnDef = args.columnDef; - this.searchTerm = args.searchTerm; + this.searchTerms = args.searchTerms || []; + + // filter input can only have 1 search term, so we will use the 1st array index if it exist + const searchTerms = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || []; + const searchTerm = typeof searchTerms[0] === 'boolean' ? `${searchTerms[0]}` : searchTerms[0]; // step 1, create HTML string template const filterTemplate = this.buildTemplateHtmlString(); // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled - this.$filterElm = this.createDomElement(filterTemplate); + this.$filterElm = this.createDomElement(filterTemplate, searchTerm); // step 3, subscribe to the keyup event and run the callback when that happens this.$filterElm.keyup((e: any) => this.callback(e, { columnDef: this.columnDef })); @@ -76,13 +80,13 @@ export class CustomInputFilter implements Filter { * From the html template string, create a DOM element * @param filterTemplate */ - private createDomElement(filterTemplate: string) { + private createDomElement(filterTemplate: string, searchTerm?: SearchTerm) { const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id); $($headerElm).empty(); // create the DOM element & add an ID and filter class const $filterElm = $(filterTemplate); - const searchTerm = (typeof this.searchTerm === 'boolean') ? `${this.searchTerm}` : this.searchTerm; + $filterElm.val(searchTerm); $filterElm.attr('id', `filter-${this.columnDef.id}`); $filterElm.data('columnId', this.columnDef.id); diff --git a/src/app/examples/grid-clientside.component.ts b/src/app/examples/grid-clientside.component.ts index 6949fe760..179fcc956 100644 --- a/src/app/examples/grid-clientside.component.ts +++ b/src/app/examples/grid-clientside.component.ts @@ -120,9 +120,9 @@ export class GridClientSideComponent implements OnInit { presets: { filters: [ { columnId: 'duration', searchTerms: [2, 22, 44] }, - // { columnId: 'complete', searchTerm: '5', operator: '>' }, - { columnId: 'usDateShort', operator: '<', searchTerm: '4/20/25' }, - // { columnId: 'effort-driven', searchTerm: true } + // { columnId: 'complete', searchTerms: ['5'], operator: '>' }, + { columnId: 'usDateShort', operator: '<', searchTerms: ['4/20/25'] }, + // { columnId: 'effort-driven', searchTerms: [true] } ], sorters: [ { columnId: 'duration', direction: 'DESC' }, diff --git a/src/app/examples/grid-graphql.component.ts b/src/app/examples/grid-graphql.component.ts index bda69c29f..cdf278327 100644 --- a/src/app/examples/grid-graphql.component.ts +++ b/src/app/examples/grid-graphql.component.ts @@ -98,8 +98,8 @@ export class GridGraphqlComponent implements OnInit, OnDestroy { presets: { // you can also type operator as string, e.g.: operator: 'EQ' filters: [ - { columnId: 'gender', searchTerm: 'male', operator: OperatorType.equal }, - { columnId: 'name', searchTerm: 'John Doe', operator: OperatorType.contains }, + { columnId: 'gender', searchTerms: ['male'], operator: OperatorType.equal }, + { columnId: 'name', searchTerms: ['John Doe'], operator: OperatorType.contains }, { columnId: 'company', searchTerms: ['xyz'], operator: 'IN' } ], sorters: [ diff --git a/src/app/examples/grid-rowselection.component.ts b/src/app/examples/grid-rowselection.component.ts index e0dc6411b..dc7d080ab 100644 --- a/src/app/examples/grid-rowselection.component.ts +++ b/src/app/examples/grid-rowselection.component.ts @@ -11,7 +11,7 @@ export class GridRowSelectionComponent implements OnInit, OnDestroy { Row selection, single or multi-select (Wiki docs). `; diff --git a/src/app/examples/swt-common-grid.component.ts b/src/app/examples/swt-common-grid.component.ts index ca5afbcf7..25eddd7ea 100644 --- a/src/app/examples/swt-common-grid.component.ts +++ b/src/app/examples/swt-common-grid.component.ts @@ -344,7 +344,7 @@ export class SwtCommonGridComponent implements OnInit, AfterViewInit, BackendSer this.filteredGridColumns = ''; for (let idx = 0; idx < this.columnDefinitions.length; idx++) { if (args.columnFilters.hasOwnProperty(this.columnDefinitions[idx].field)) { - this.filteredGridColumns += args.columnFilters[this.columnDefinitions[idx].field].searchTerm + '|'; + this.filteredGridColumns += args.columnFilters[this.columnDefinitions[idx].field].searchTerms[0] + '|'; } else { this.filteredGridColumns += 'All|'; } diff --git a/src/app/modules/angular-slickgrid/filter-conditions/booleanFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/booleanFilterCondition.ts index e5c0a1432..6110548c6 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/booleanFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/booleanFilterCondition.ts @@ -5,5 +5,6 @@ function parseBoolean(str: number | string) { } export const booleanFilterCondition: FilterCondition = (options: FilterConditionOption) => { - return parseBoolean(options.cellValue) === parseBoolean(options.searchTerm); + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + return parseBoolean(options.cellValue) === parseBoolean(searchTerms[0]); }; diff --git a/src/app/modules/angular-slickgrid/filter-conditions/dateFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/dateFilterCondition.ts index e1ea1abe4..b84d9d04b 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/dateFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/dateFilterCondition.ts @@ -5,13 +5,14 @@ import * as moment_ from 'moment-mini'; const moment = moment_; // patch to fix rollup "moment has no default export" issue, document here https://github.com/rollup/rollup/issues/670 export const dateFilterCondition: FilterCondition = (options: FilterConditionOption) => { + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; const filterSearchType = options.filterSearchType || FieldType.dateIso; const searchDateFormat = mapMomentDateFormatWithFieldType(filterSearchType); - if (!moment(options.cellValue, moment.ISO_8601).isValid() || !moment(options.searchTerm, searchDateFormat, true).isValid()) { + if (!moment(options.cellValue, moment.ISO_8601).isValid() || !moment(searchTerms[0], searchDateFormat, true).isValid()) { return true; } const dateCell = moment(options.cellValue); - const dateSearch = moment(options.searchTerm); + const dateSearch = moment(searchTerms[0]); // run the filter condition with date in Unix Timestamp format return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10)); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/dateIsoFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/dateIsoFilterCondition.ts index a99bbc6a7..d8341ff8d 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/dateIsoFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/dateIsoFilterCondition.ts @@ -6,11 +6,12 @@ const moment = moment_; // patch to fix rollup "moment has no default export" is const FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateIso); export const dateIsoFilterCondition: FilterCondition = (options: FilterConditionOption) => { - if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(options.searchTerm, FORMAT, true).isValid()) { + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerms[0], FORMAT, true).isValid()) { return true; } const dateCell = moment(options.cellValue, FORMAT, true); - const dateSearch = moment(options.searchTerm, FORMAT, true); + const dateSearch = moment(searchTerms[0], FORMAT, true); // run the filter condition with date in Unix Timestamp format return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10)); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/dateUsFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/dateUsFilterCondition.ts index 2c025aef1..92b8cfe31 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/dateUsFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/dateUsFilterCondition.ts @@ -6,11 +6,12 @@ const moment = moment_; // patch to fix rollup "moment has no default export" is const FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUs); export const dateUsFilterCondition: FilterCondition = (options: FilterConditionOption) => { - if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(options.searchTerm, FORMAT, true).isValid()) { + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerms[0], FORMAT, true).isValid()) { return true; } const dateCell = moment(options.cellValue, FORMAT, true); - const dateSearch = moment(options.searchTerm, FORMAT, true); + const dateSearch = moment(searchTerms[0], FORMAT, true); // run the filter condition with date in Unix Timestamp format return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10)); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/dateUsShortFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/dateUsShortFilterCondition.ts index abac81e93..3402fdb1d 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/dateUsShortFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/dateUsShortFilterCondition.ts @@ -6,11 +6,12 @@ const moment = moment_; // patch to fix rollup "moment has no default export" is const FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUsShort); export const dateUsShortFilterCondition: FilterCondition = (options: FilterConditionOption) => { - if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(options.searchTerm, FORMAT, true).isValid()) { + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + if (!moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerms[0], FORMAT, true).isValid()) { return true; } const dateCell = moment(options.cellValue, FORMAT, true); - const dateSearch = moment(options.searchTerm, FORMAT, true); + const dateSearch = moment(searchTerms[0], FORMAT, true); // run the filter condition with date in Unix Timestamp format return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10)); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/dateUtcFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/dateUtcFilterCondition.ts index 73c922c74..94e2be626 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/dateUtcFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/dateUtcFilterCondition.ts @@ -5,12 +5,13 @@ import * as moment_ from 'moment-mini'; const moment = moment_; // patch to fix rollup "moment has no default export" issue, document here https://github.com/rollup/rollup/issues/670 export const dateUtcFilterCondition: FilterCondition = (options: FilterConditionOption) => { + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; const searchDateFormat = mapMomentDateFormatWithFieldType(options.filterSearchType || options.fieldType); - if (!moment(options.cellValue, moment.ISO_8601).isValid() || !moment(options.searchTerm, searchDateFormat, true).isValid()) { + if (!moment(options.cellValue, moment.ISO_8601).isValid() || !moment(searchTerms[0], searchDateFormat, true).isValid()) { return true; } const dateCell = moment(options.cellValue, moment.ISO_8601, true); - const dateSearch = moment(options.searchTerm, searchDateFormat, true); + const dateSearch = moment(searchTerms[0], searchDateFormat, true); // run the filter condition with date in Unix Timestamp format return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10)); diff --git a/src/app/modules/angular-slickgrid/filter-conditions/numberFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/numberFilterCondition.ts index 110c79d9a..009cf53d7 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/numberFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/numberFilterCondition.ts @@ -3,7 +3,8 @@ import { testFilterCondition } from './filterUtilities'; export const numberFilterCondition: FilterCondition = (options: FilterConditionOption) => { const cellValue = parseFloat(options.cellValue); - const searchTerm = (typeof options.searchTerm === 'string') ? parseFloat(options.searchTerm) : options.searchTerm; + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + const searchTerm = typeof searchTerms[0] === 'string' ? parseFloat(searchTerms[0]) : searchTerms[0]; return testFilterCondition(options.operator || '==', cellValue, searchTerm); }; diff --git a/src/app/modules/angular-slickgrid/filter-conditions/stringFilterCondition.ts b/src/app/modules/angular-slickgrid/filter-conditions/stringFilterCondition.ts index 7b8a3a09b..c009f52bc 100644 --- a/src/app/modules/angular-slickgrid/filter-conditions/stringFilterCondition.ts +++ b/src/app/modules/angular-slickgrid/filter-conditions/stringFilterCondition.ts @@ -7,7 +7,8 @@ export const stringFilterCondition: FilterCondition = (options: FilterConditionO // make both the cell value and search value lower for case insensitive comparison const cellValue = options.cellValue.toLowerCase(); - const searchTerm = (typeof options.searchTerm === 'string') ? options.searchTerm.toLowerCase() : options.searchTerm; + const searchTerms = Array.isArray(options.searchTerms) && options.searchTerms[0] || []; + const searchTerm = typeof searchTerms[0] === 'string' ? searchTerms[0].toLowerCase() : searchTerms[0]; if (options.operator === '*' || options.operator === OperatorType.endsWith) { return cellValue.endsWith(searchTerm); diff --git a/src/app/modules/angular-slickgrid/filters/compoundDateFilter.ts b/src/app/modules/angular-slickgrid/filters/compoundDateFilter.ts index f76892526..bb63bd153 100644 --- a/src/app/modules/angular-slickgrid/filters/compoundDateFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/compoundDateFilter.ts @@ -18,14 +18,18 @@ export class CompoundDateFilter implements Filter { private _currentValue: string; flatInstance: any; grid: any; - gridOptions: GridOption; operator: OperatorType | OperatorString; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; constructor(private translate: TranslateService) {} + /** Getter for the Grid Options pulled through the Grid Object */ + private get gridOptions(): GridOption { + return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {}; + } + /** * Initialize the Filter */ @@ -34,14 +38,14 @@ export class CompoundDateFilter implements Filter { this.callback = args.callback; this.columnDef = args.columnDef; this.operator = args.operator; - this.searchTerm = args.searchTerm; - if (this.grid && typeof this.grid.getOptions === 'function') { - this.gridOptions = this.grid.getOptions(); - } + this.searchTerms = args.searchTerms || []; + + // date input can only have 1 search term, so we will use the 1st array index if it exist + const searchTerm = ((Array.isArray(this.searchTerms) && this.searchTerms[0]) || '') as string; // step 1, create the DOM Element of the filter which contain the compound Operator+Input - // and initialize it if searchTerm is filled - this.$filterElm = this.createDomElement(); + // and initialize it if searchTerms is filled + this.$filterElm = this.createDomElement(searchTerm); // step 3, subscribe to the keyup event and run the callback when that happens // also add/remove "filled" class for styling purposes @@ -76,9 +80,9 @@ export class CompoundDateFilter implements Filter { /** * Set value(s) on the DOM element */ - setValues(values: SearchTerm) { - if (values) { - this.flatInstance.setDate(values); + setValues(values: SearchTerm[]) { + if (values && Array.isArray(values)) { + this.flatInstance.setDate(values[0]); } } @@ -86,7 +90,7 @@ export class CompoundDateFilter implements Filter { // private functions // ------------------ - private buildDatePickerInput(searchTerm: SearchTerm) { + private buildDatePickerInput(searchTerm?: SearchTerm) { const inputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.type || FieldType.dateIso); const outputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.outputType || this.columnDef.type || FieldType.dateUtc); let currentLocale = this.getCurrentLocale(this.columnDef, this.gridOptions) || ''; @@ -151,13 +155,12 @@ export class CompoundDateFilter implements Filter { /** * Create the DOM element */ - private createDomElement() { + private createDomElement(searchTerm?: SearchTerm) { const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id); $($headerElm).empty(); - const searchTerm = (this.searchTerm || '') as string; if (searchTerm) { - this._currentValue = searchTerm; + this._currentValue = searchTerm as string; } // create the DOM Select dropdown for the Operator @@ -191,7 +194,7 @@ export class CompoundDateFilter implements Filter { } // if there's a search term, we will add the "filled" class for styling purposes - if (this.searchTerm) { + if (searchTerm) { $filterContainerElm.addClass('filled'); } @@ -224,7 +227,7 @@ export class CompoundDateFilter implements Filter { private onTriggerEvent(e: Event | undefined) { const selectedOperator = this.$selectOperatorElm.find('option:selected').text(); (this._currentValue) ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled'); - this.callback(e, { columnDef: this.columnDef, searchTerm: this._currentValue, operator: selectedOperator || '=' }); + this.callback(e, { columnDef: this.columnDef, searchTerms: [this._currentValue], operator: selectedOperator || '=' }); } private hide() { diff --git a/src/app/modules/angular-slickgrid/filters/compoundInputFilter.ts b/src/app/modules/angular-slickgrid/filters/compoundInputFilter.ts index c3866cae0..708e512d8 100644 --- a/src/app/modules/angular-slickgrid/filters/compoundInputFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/compoundInputFilter.ts @@ -13,14 +13,18 @@ export class CompoundInputFilter implements Filter { private $filterInputElm: any; private $selectOperatorElm: any; grid: any; - gridOptions: GridOption; operator: OperatorType | OperatorString; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; constructor(private translate: TranslateService) {} + /** Getter for the Grid Options pulled through the Grid Object */ + private get gridOptions(): GridOption { + return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {}; + } + /** * Initialize the Filter */ @@ -29,14 +33,14 @@ export class CompoundInputFilter implements Filter { this.callback = args.callback; this.columnDef = args.columnDef; this.operator = args.operator; - this.searchTerm = args.searchTerm; - if (this.grid && typeof this.grid.getOptions === 'function') { - this.gridOptions = this.grid.getOptions(); - } + this.searchTerms = args.searchTerms || []; + + // filter input can only have 1 search term, so we will use the 1st array index if it exist + const searchTerm = ((Array.isArray(this.searchTerms) && this.searchTerms[0]) || '') as string; // step 1, create the DOM Element of the filter which contain the compound Operator+Input - // and initialize it if searchTerm is filled - this.$filterElm = this.createDomElement(); + // and initialize it if searchTerms is filled + this.$filterElm = this.createDomElement(searchTerm); // step 3, subscribe to the keyup event and run the callback when that happens // also add/remove "filled" class for styling purposes @@ -74,9 +78,9 @@ export class CompoundInputFilter implements Filter { /** * Set value(s) on the DOM element */ - setValues(values: SearchTerm) { - if (values) { - this.$filterElm.val(values); + setValues(values: SearchTerm[]) { + if (values && Array.isArray(values)) { + this.$filterElm.val(values[0]); } } @@ -134,7 +138,7 @@ export class CompoundInputFilter implements Filter { /** * Create the DOM element */ - private createDomElement() { + private createDomElement(searchTerm?: SearchTerm) { const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id); $($headerElm).empty(); @@ -161,7 +165,6 @@ export class CompoundInputFilter implements Filter { $filterContainerElm.append($containerInputGroup); $filterContainerElm.attr('id', `filter-${this.columnDef.id}`); - const searchTerm = (typeof this.searchTerm === 'boolean') ? `${this.searchTerm}` : this.searchTerm; this.$filterInputElm.val(searchTerm); this.$filterInputElm.data('columnId', this.columnDef.id); @@ -170,7 +173,7 @@ export class CompoundInputFilter implements Filter { } // if there's a search term, we will add the "filled" class for styling purposes - if (this.searchTerm) { + if (searchTerm) { $filterContainerElm.addClass('filled'); } @@ -186,6 +189,6 @@ export class CompoundInputFilter implements Filter { const selectedOperator = this.$selectOperatorElm.find('option:selected').text(); const value = this.$filterInputElm.val(); (value) ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled'); - this.callback(e, { columnDef: this.columnDef, searchTerm: value, operator: selectedOperator || '' }); + this.callback(e, { columnDef: this.columnDef, searchTerms: [value], operator: selectedOperator || '' }); } } diff --git a/src/app/modules/angular-slickgrid/filters/inputFilter.ts b/src/app/modules/angular-slickgrid/filters/inputFilter.ts index 7fd982e4a..a9aee72c0 100644 --- a/src/app/modules/angular-slickgrid/filters/inputFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/inputFilter.ts @@ -6,13 +6,17 @@ declare var $: any; export class InputFilter implements Filter { private $filterElm: any; grid: any; - gridOptions: GridOption; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; constructor() {} + /** Getter for the Grid Options pulled through the Grid Object */ + private get gridOptions(): GridOption { + return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {}; + } + /** * Initialize the Filter */ @@ -20,16 +24,17 @@ export class InputFilter implements Filter { this.grid = args.grid; this.callback = args.callback; this.columnDef = args.columnDef; - this.searchTerm = args.searchTerm; - if (this.grid && typeof this.grid.getOptions === 'function') { - this.gridOptions = this.grid.getOptions(); - } + this.searchTerms = args.searchTerms || []; + + // filter input can only have 1 search term, so we will use the 1st array index if it exist + const searchTerms = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || []; + const searchTerm = typeof searchTerms[0] === 'boolean' ? `${searchTerms[0]}` : searchTerms[0]; // step 1, create HTML string template const filterTemplate = this.buildTemplateHtmlString(); // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled - this.$filterElm = this.createDomElement(filterTemplate); + this.$filterElm = this.createDomElement(filterTemplate, searchTerm); // step 3, subscribe to the keyup event and run the callback when that happens // also add/remove "filled" class for styling purposes @@ -85,19 +90,19 @@ export class InputFilter implements Filter { * From the html template string, create a DOM element * @param filterTemplate */ - private createDomElement(filterTemplate: string) { + private createDomElement(filterTemplate: string, searchTerm?: SearchTerm) { const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id); $($headerElm).empty(); // create the DOM element & add an ID and filter class const $filterElm = $(filterTemplate); - const searchTerm = (typeof this.searchTerm === 'boolean') ? `${this.searchTerm}` : this.searchTerm; + $filterElm.val(searchTerm); $filterElm.attr('id', `filter-${this.columnDef.id}`); $filterElm.data('columnId', this.columnDef.id); // if there's a search term, we will add the "filled" class for styling purposes - if (this.searchTerm) { + if (searchTerm) { $filterElm.addClass('filled'); } diff --git a/src/app/modules/angular-slickgrid/filters/multipleSelectFilter.ts b/src/app/modules/angular-slickgrid/filters/multipleSelectFilter.ts index 6a7410775..228c0f960 100644 --- a/src/app/modules/angular-slickgrid/filters/multipleSelectFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/multipleSelectFilter.ts @@ -19,7 +19,6 @@ declare var $: any; export class MultipleSelectFilter implements Filter { $filterElm: any; grid: any; - gridOptions: GridOption; searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; @@ -61,6 +60,11 @@ export class MultipleSelectFilter implements Filter { }; } + /** Getter for the Grid Options pulled through the Grid Object */ + private get gridOptions(): GridOption { + return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {}; + } + /** * Initialize the filter template */ @@ -79,7 +83,6 @@ export class MultipleSelectFilter implements Filter { this.valueName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.value : 'value'; let newCollection = this.columnDef.filter.collection || []; - this.gridOptions = this.grid.getOptions(); // user might want to filter certain items of the collection if (this.gridOptions.params && this.columnDef.filter.collectionFilterBy) { diff --git a/src/app/modules/angular-slickgrid/filters/selectFilter.ts b/src/app/modules/angular-slickgrid/filters/selectFilter.ts index c58e84e08..dbcce1bd4 100644 --- a/src/app/modules/angular-slickgrid/filters/selectFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/selectFilter.ts @@ -7,7 +7,7 @@ declare var $: any; export class SelectFilter implements Filter { $filterElm: any; grid: any; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; @@ -20,13 +20,17 @@ export class SelectFilter implements Filter { this.grid = args.grid; this.callback = args.callback; this.columnDef = args.columnDef; - this.searchTerm = args.searchTerm; + this.searchTerms = args.searchTerms || []; + + // filter input can only have 1 search term, so we will use the 1st array index if it exist + const searchTerms = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || []; + const searchTerm = typeof searchTerms[0] === 'boolean' ? `${searchTerms[0]}` : searchTerms[0]; // step 1, create HTML string template const filterTemplate = this.buildTemplateHtmlString(); // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled - this.$filterElm = this.createDomElement(filterTemplate); + this.$filterElm = this.createDomElement(filterTemplate, searchTerm); // step 3, subscribe to the change event and run the callback when that happens // also add/remove "filled" class for styling purposes @@ -95,13 +99,12 @@ export class SelectFilter implements Filter { * From the html template string, create a DOM element * @param filterTemplate */ - private createDomElement(filterTemplate: string) { + private createDomElement(filterTemplate: string, searchTerm?: SearchTerm) { const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id); $($headerElm).empty(); // create the DOM element & add an ID and filter class const $filterElm = $(filterTemplate); - const searchTerm = (typeof this.searchTerm === 'boolean') ? `${this.searchTerm}` : this.searchTerm; $filterElm.val(searchTerm); $filterElm.attr('id', `filter-${this.columnDef.id}`); $filterElm.data('columnId', this.columnDef.id); diff --git a/src/app/modules/angular-slickgrid/filters/singleSelectFilter.ts b/src/app/modules/angular-slickgrid/filters/singleSelectFilter.ts index 0f41d4dfd..902374523 100644 --- a/src/app/modules/angular-slickgrid/filters/singleSelectFilter.ts +++ b/src/app/modules/angular-slickgrid/filters/singleSelectFilter.ts @@ -19,8 +19,7 @@ declare var $: any; export class SingleSelectFilter implements Filter { $filterElm: any; grid: any; - gridOptions: GridOption; - searchTerm: SearchTerm; + searchTerms: SearchTerm[]; columnDef: Column; callback: FilterCallback; defaultOptions: MultipleSelectOption; @@ -48,11 +47,16 @@ export class SingleSelectFilter implements Filter { this.isFilled = false; this.$filterElm.removeClass('filled').siblings('div .search-filter').removeClass('filled'); } - this.callback(undefined, { columnDef: this.columnDef, operator: 'EQ', searchTerm: selectedItem }); + this.callback(undefined, { columnDef: this.columnDef, operator: 'EQ', searchTerms: [selectedItem] }); } }; } + /** Getter for the Grid Options pulled through the Grid Object */ + private get gridOptions(): GridOption { + return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {}; + } + /** * Initialize the Filter */ @@ -60,7 +64,7 @@ export class SingleSelectFilter implements Filter { this.grid = args.grid; this.callback = args.callback; this.columnDef = args.columnDef; - this.searchTerm = args.searchTerm; + this.searchTerms = args.searchTerms; if (!this.grid || !this.columnDef || !this.columnDef.filter || !this.columnDef.filter.collection) { throw new Error(`[Angular-SlickGrid] You need to pass a "collection" for the MultipleSelect Filter to work correctly. Also each option should include a value/label pair (or value/labelKey when using Locale). For example:: { filter: type: FilterType.multipleSelect, collection: [{ value: true, label: 'True' }, { value: false, label: 'False'}] }`); @@ -71,7 +75,6 @@ export class SingleSelectFilter implements Filter { this.valueName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.value : 'value'; let newCollection = this.columnDef.filter.collection || []; - this.gridOptions = this.grid.getOptions(); // user might want to filter certain items of the collection if (this.gridOptions.params && this.columnDef.filter.collectionFilterBy) { @@ -85,8 +88,11 @@ export class SingleSelectFilter implements Filter { newCollection = this.collectionService.sortCollection(newCollection, sortBy, this.enableTranslateLabel); } + const searchTerms = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || []; + const searchTerm = typeof searchTerms[0] === 'boolean' ? `${searchTerms[0]}` : searchTerms[0]; + // step 1, create HTML string template - const filterTemplate = this.buildTemplateHtmlString(newCollection || []); + const filterTemplate = this.buildTemplateHtmlString(newCollection || [], searchTerm); // step 2, create the DOM Element of the filter & pre-load search term this.createDomElement(filterTemplate); @@ -102,7 +108,7 @@ export class SingleSelectFilter implements Filter { this.$filterElm.multipleSelect('setSelects', []); if (triggerFilterChange) { - this.callback(undefined, { columnDef: this.columnDef, operator: 'IN', searchTerm: undefined }); + this.callback(undefined, { columnDef: this.columnDef, operator: 'IN', searchTerms: [] }); } } } @@ -133,7 +139,7 @@ export class SingleSelectFilter implements Filter { /** * Create the HTML template as a string */ - private buildTemplateHtmlString(optionCollection: any[]) { + private buildTemplateHtmlString(optionCollection: any[], searchTerm?: SearchTerm) { let options = ''; optionCollection.forEach((option: SelectOption) => { if (!option || (option[this.labelName] === undefined && option.labelKey === undefined)) { @@ -141,7 +147,7 @@ export class SingleSelectFilter implements Filter { } const labelKey = (option.labelKey || option[this.labelName]) as string; - const selected = (option[this.valueName] === this.searchTerm) ? 'selected' : ''; + const selected = (option[this.valueName] === searchTerm) ? 'selected' : ''; const textLabel = ((option.labelKey || this.columnDef.filter.enableTranslateLabel) && this.translate && typeof this.translate.instant === 'function') ? this.translate.instant(labelKey || ' ') : labelKey; // html text of each select option diff --git a/src/app/modules/angular-slickgrid/models/columnFilter.interface.ts b/src/app/modules/angular-slickgrid/models/columnFilter.interface.ts index 49f65dee4..e1140032a 100644 --- a/src/app/modules/angular-slickgrid/models/columnFilter.interface.ts +++ b/src/app/modules/angular-slickgrid/models/columnFilter.interface.ts @@ -23,9 +23,6 @@ export interface ColumnFilter { /** Custom Filter */ customFilter?: Filter; - /** Search term (singular) */ - searchTerm?: SearchTerm; - /** Search terms (collection) */ searchTerms?: SearchTerm[]; diff --git a/src/app/modules/angular-slickgrid/models/currentFilter.interface.ts b/src/app/modules/angular-slickgrid/models/currentFilter.interface.ts index 607ba7f0e..3ba2d6d3a 100644 --- a/src/app/modules/angular-slickgrid/models/currentFilter.interface.ts +++ b/src/app/modules/angular-slickgrid/models/currentFilter.interface.ts @@ -3,6 +3,5 @@ import { OperatorString, OperatorType, SearchTerm } from './../models/index'; export interface CurrentFilter { columnId: string; operator?: OperatorType | OperatorString; - searchTerm?: SearchTerm; searchTerms?: SearchTerm[]; } diff --git a/src/app/modules/angular-slickgrid/models/filter.interface.ts b/src/app/modules/angular-slickgrid/models/filter.interface.ts index 57acb1248..43444932a 100644 --- a/src/app/modules/angular-slickgrid/models/filter.interface.ts +++ b/src/app/modules/angular-slickgrid/models/filter.interface.ts @@ -13,9 +13,6 @@ export interface Filter { /** SlickGrid grid object */ grid: any; - /** Defined search term to pre-load */ - searchTerm?: SearchTerm; - /** Array of defined search terms to pre-load */ searchTerms?: SearchTerm[]; diff --git a/src/app/modules/angular-slickgrid/models/filterArguments.interface.ts b/src/app/modules/angular-slickgrid/models/filterArguments.interface.ts index e06d9b384..dff3dc3d4 100644 --- a/src/app/modules/angular-slickgrid/models/filterArguments.interface.ts +++ b/src/app/modules/angular-slickgrid/models/filterArguments.interface.ts @@ -6,7 +6,6 @@ export interface FilterArguments { columnDef: Column; callback: FilterCallback; operator?: OperatorType | OperatorString; - searchTerm?: SearchTerm; searchTerms?: SearchTerm[]; i18n?: TranslateService; params?: any | any[]; diff --git a/src/app/modules/angular-slickgrid/models/filterCallback.interface.ts b/src/app/modules/angular-slickgrid/models/filterCallback.interface.ts index a9c8fde66..682d8bf20 100644 --- a/src/app/modules/angular-slickgrid/models/filterCallback.interface.ts +++ b/src/app/modules/angular-slickgrid/models/filterCallback.interface.ts @@ -3,7 +3,6 @@ import { Column, OperatorString, SearchTerm } from './../models/index'; export interface FilterCallbackArg { columnDef: Column; operator?: OperatorString; - searchTerm?: SearchTerm; searchTerms?: SearchTerm[]; } diff --git a/src/app/modules/angular-slickgrid/models/filterChangedArgs.interface.ts b/src/app/modules/angular-slickgrid/models/filterChangedArgs.interface.ts index 0a9ec7b0d..0c928aac5 100644 --- a/src/app/modules/angular-slickgrid/models/filterChangedArgs.interface.ts +++ b/src/app/modules/angular-slickgrid/models/filterChangedArgs.interface.ts @@ -4,6 +4,5 @@ import { ColumnFilters } from './columnFilters.interface'; export interface FilterChangedArgs { columnFilters: ColumnFilters; grid: any; - searchTerm: SearchTerm; searchTerms: SearchTerm[]; } diff --git a/src/app/modules/angular-slickgrid/models/filterConditionOption.interface.ts b/src/app/modules/angular-slickgrid/models/filterConditionOption.interface.ts index c8afec251..b410806d4 100644 --- a/src/app/modules/angular-slickgrid/models/filterConditionOption.interface.ts +++ b/src/app/modules/angular-slickgrid/models/filterConditionOption.interface.ts @@ -6,6 +6,5 @@ export interface FilterConditionOption { cellValueLastChar?: string; fieldType: FieldType; filterSearchType?: FieldType; - searchTerm?: string | number; searchTerms?: string[] | number[]; } diff --git a/src/app/modules/angular-slickgrid/services/filter.service.ts b/src/app/modules/angular-slickgrid/services/filter.service.ts index 49243416e..241fa5f7e 100644 --- a/src/app/modules/angular-slickgrid/services/filter.service.ts +++ b/src/app/modules/angular-slickgrid/services/filter.service.ts @@ -301,8 +301,6 @@ export class FilterService { if (columnFilter && columnFilter.searchTerms) { filter.searchTerms = columnFilter.searchTerms; - } else { - filter.searchTerm = (columnFilter && (columnFilter.searchTerm !== undefined || columnFilter.searchTerm !== null)) ? columnFilter.searchTerm : undefined; } if (columnFilter.operator) { filter.operator = columnFilter.operator; @@ -315,13 +313,12 @@ export class FilterService { callbackSearchEvent(e: Event | undefined, args: FilterCallbackArg) { if (args) { - const searchTerm = args.searchTerm ? args.searchTerm : ((e && e.target) ? (e.target as HTMLInputElement).value : undefined); const searchTerms = (args.searchTerms && Array.isArray(args.searchTerms)) ? args.searchTerms : undefined; const columnDef = args.columnDef || null; const columnId = columnDef ? (columnDef.id || '') : ''; const operator = args.operator || undefined; - if (!searchTerm && (!searchTerms || (Array.isArray(searchTerms) && searchTerms.length === 0))) { + if (!searchTerms || (Array.isArray(searchTerms) && searchTerms.length === 0)) { // delete the property from the columnFilters when it becomes empty // without doing this, it would leave an incorrect state of the previous column filters when filtering on another column delete this._columnFilters[columnId]; @@ -330,7 +327,6 @@ export class FilterService { const colFilter: ColumnFilter = { columnId: colId, columnDef, - searchTerm, searchTerms, }; if (operator) { @@ -344,7 +340,6 @@ export class FilterService { columnDef: args.columnDef || null, columnFilters: this._columnFilters, operator, - searchTerm, searchTerms, serviceOptions: this._onFilterChangedOptions, grid: this._grid @@ -358,26 +353,22 @@ export class FilterService { if (columnDef && columnId !== 'selector' && columnDef.filterable) { let searchTerms: SearchTerm[] | undefined; - let searchTerm: SearchTerm | undefined; let operator: OperatorString | OperatorType; if (this._columnFilters[columnDef.id]) { - searchTerm = this._columnFilters[columnDef.id].searchTerm || undefined; searchTerms = this._columnFilters[columnDef.id].searchTerms || undefined; operator = this._columnFilters[columnDef.id].operator || undefined; } else if (columnDef.filter) { // when hiding/showing (with Column Picker or Grid Menu), it will try to re-create yet again the filters (since SlickGrid does a re-render) // because of that we need to first get searchTerm(s) from the columnFilters (that is what the user last entered) searchTerms = columnDef.filter.searchTerms || undefined; - searchTerm = columnDef.filter.searchTerm || undefined; operator = columnDef.filter.operator || undefined; - this.updateColumnFilters(searchTerm, searchTerms, columnDef); + this.updateColumnFilters(searchTerms, columnDef); } const filterArguments: FilterArguments = { grid: this._grid, operator, - searchTerm, searchTerms, columnDef, callback: this.callbackSearchEvent.bind(this) @@ -431,8 +422,8 @@ export class FilterService { // when hiding/showing (with Column Picker or Grid Menu), it will try to re-create yet again the filters (since SlickGrid does a re-render) // we need to also set again the values in the DOM elements if the values were set by a searchTerm(s) - if ((searchTerm || searchTerms) && filter.setValues) { - filter.setValues(searchTerm || searchTerms); + if (searchTerms && filter.setValues) { + filter.setValues(searchTerms); } } } @@ -470,11 +461,6 @@ export class FilterService { const columnPreset = filters.find((presetFilter: CurrentFilter) => { return presetFilter.columnId === columnDef.id; }); - if (columnPreset && columnPreset.searchTerm) { - columnDef.filter = columnDef.filter || {}; - columnDef.filter.operator = columnPreset.operator; - columnDef.filter.searchTerm = columnPreset.searchTerm; - } if (columnPreset && columnPreset.searchTerms) { columnDef.filter = columnDef.filter || {}; columnDef.filter.operator = columnPreset.operator || columnDef.filter.operator || OperatorType.in; @@ -485,16 +471,7 @@ export class FilterService { return this._columnDefinitions; } - private updateColumnFilters(searchTerm: SearchTerm | undefined, searchTerms: SearchTerm[] | undefined, columnDef: any) { - if (searchTerm !== undefined && searchTerm !== null && searchTerm !== '') { - this._columnFilters[columnDef.id] = { - columnId: columnDef.id, - columnDef, - searchTerm, - operator: (columnDef && columnDef.filter && columnDef.filter.operator) ? columnDef.filter.operator : null, - type: (columnDef && columnDef.filter && columnDef.filter.type) ? columnDef.filter.type : FilterType.input - }; - } + private updateColumnFilters(searchTerms: SearchTerm[] | undefined, columnDef: any) { if (searchTerms) { // this._columnFilters.searchTerms = searchTerms; this._columnFilters[columnDef.id] = { diff --git a/src/app/modules/angular-slickgrid/services/graphql.service.ts b/src/app/modules/angular-slickgrid/services/graphql.service.ts index 9dfd56280..836f28401 100644 --- a/src/app/modules/angular-slickgrid/services/graphql.service.ts +++ b/src/app/modules/angular-slickgrid/services/graphql.service.ts @@ -351,7 +351,7 @@ export class GraphqlService implements BackendService { const fieldName = columnDef.queryField || columnDef.queryFieldFilter || columnDef.field || columnDef.name || ''; const searchTerms = (columnFilter ? columnFilter.searchTerms : null) || []; - let fieldSearchValue = columnFilter.searchTerm; + let fieldSearchValue = (Array.isArray(searchTerms) && searchTerms.length === 1) ? searchTerms[0] : ''; if (typeof fieldSearchValue === 'undefined') { fieldSearchValue = ''; } @@ -372,7 +372,7 @@ export class GraphqlService implements BackendService { } // when having more than 1 search term (we need to create a CSV string for GraphQL "IN" or "NOT IN" filter search) - if (searchTerms && searchTerms.length > 0) { + if (searchTerms && searchTerms.length > 1) { searchValue = searchTerms.join(','); } else if (typeof searchValue === 'string') { // escaping the search value @@ -546,8 +546,6 @@ export class GraphqlService implements BackendService { } if (Array.isArray(filter.searchTerms)) { tmpFilter.searchTerms = filter.searchTerms; - } else { - tmpFilter.searchTerm = filter.searchTerm; } return tmpFilter; }); diff --git a/src/app/modules/angular-slickgrid/services/grid-odata.service.ts b/src/app/modules/angular-slickgrid/services/grid-odata.service.ts index 6f1f41390..f5838e0f8 100644 --- a/src/app/modules/angular-slickgrid/services/grid-odata.service.ts +++ b/src/app/modules/angular-slickgrid/services/grid-odata.service.ts @@ -203,7 +203,7 @@ export class GridOdataService implements BackendService { let fieldName = columnDef.queryField || columnDef.queryFieldFilter || columnDef.field || columnDef.name || ''; const fieldType = columnDef.type || 'string'; const searchTerms = (columnFilter ? columnFilter.searchTerms : null) || []; - let fieldSearchValue = columnFilter.searchTerm; + let fieldSearchValue = (Array.isArray(searchTerms) && searchTerms.length === 1) ? searchTerms[0] : ''; if (typeof fieldSearchValue === 'undefined') { fieldSearchValue = ''; } @@ -220,7 +220,7 @@ export class GridOdataService implements BackendService { const bypassOdataQuery = columnFilter.bypassBackendQuery || false; // no need to query if search value is empty - if (fieldName && searchValue === '') { + if (fieldName && searchValue === '' && searchTerms.length === 0) { this.removeColumnFilter(fieldName); continue; } @@ -244,7 +244,7 @@ export class GridOdataService implements BackendService { } // when having more than 1 search term (then check if we have a "IN" or "NOT IN" filter search) - if (searchTerms && searchTerms.length > 0) { + if (searchTerms && searchTerms.length > 1) { const tmpSearchTerms = []; if (operator === 'IN') { @@ -405,8 +405,6 @@ export class GridOdataService implements BackendService { } if (Array.isArray(filter.searchTerms)) { tmpFilter.searchTerms = filter.searchTerms; - } else { - tmpFilter.searchTerm = filter.searchTerm; } return tmpFilter; });