diff --git a/examples/ng-cli/src/app/shared/ng2-filter.pipe.ts b/examples/ng-cli/src/app/shared/ng2-filter.pipe.ts index 3ffeb009..60e7afef 100644 --- a/examples/ng-cli/src/app/shared/ng2-filter.pipe.ts +++ b/examples/ng-cli/src/app/shared/ng2-filter.pipe.ts @@ -64,6 +64,12 @@ export class Ng2FilterPipe { } } + /** + * Filter value by $or + * + * @param filter + * @returns {(value:any)=>boolean} + */ private filterByOr(filter: any[]) { return (value: any) => { let hasMatch = false; diff --git a/src/ng2-filter.pipe.spec.ts b/src/ng2-filter.pipe.spec.ts index 45c62e12..a7faa952 100644 --- a/src/ng2-filter.pipe.spec.ts +++ b/src/ng2-filter.pipe.spec.ts @@ -186,7 +186,7 @@ describe('Pipe: Ng2FilterPipe', () => { expect(pipe.transform(objects, filter)).toEqual([objects[0], objects[1], objects[3]]); }); - it('should filter array by array', () => { + it('should filter array by using $or operator', () => { const objects = [ { languages: ['English'] }, { languages: ['English', 'German'] }, @@ -194,25 +194,34 @@ describe('Pipe: Ng2FilterPipe', () => { { languages: ['German', 'English'] } ]; - let filter = { languages: ['English'] }; + expect(pipe.transform(objects, { languages: { $or: ['English', 'German'] }})).toEqual(objects); + }); - expect(pipe.transform(objects, filter)).toEqual([objects[0], objects[1], objects[3]]); + it('should filter string by using $or operator', () => { + const objects = [ + { languages: 'English' }, + { languages: 'German' } + ]; - filter = { languages: ['English', 'German'] }; - expect(pipe.transform(objects, filter)).toEqual(objects); + expect(pipe.transform(objects, { languages: { $or: ['English', 'German'] }})).toEqual(objects); + expect(pipe.transform(objects, { languages: { $or: ['English'] }})).toEqual([objects[0]]); + expect(pipe.transform(objects, { languages: { $or: ['asd'] }})).toEqual([]); + }); - filter = { languages: ['German'] }; - expect(pipe.transform(objects, filter)).toEqual([ objects[1], objects[2], objects[3]]); + it('should filter array of string by using $or operator', () => { + const objects = [ 'English', 'German' ]; + expect(pipe.transform(objects, { $or: ['English'] })).toEqual([objects[0]]); }); - // it('should filter by using $or operator', () => { - // const objects = [ - // { - // valueA: 1, - // valueB: 2 - // } - // ]; - // - // expect(pipe.transform(objects, { $or: [{ valueA: 1 }, { valueB: 2 }] })).toEqual(objects); - // }); + it('should filter by using $or operator and another field', () => { + const objects = [ + { languages: ['English', 'German'], age: 30 }, + { languages: 'German', age: 27 } + ]; + + expect(pipe.transform(objects, { languages: { $or: ['English', 'German'] }, age: 27 })).toEqual([objects[1]]); + expect(pipe.transform(objects, { languages: { $or: ['English', 'German'] }, age: 30 })).toEqual([objects[0]]); + expect(pipe.transform(objects, { languages: { $or: ['English', 'German'] }, age: 31 })).toEqual([]); + expect(pipe.transform(objects, { languages: { $or: ['English'] }, age: 27 })).toEqual([]); + }); }); diff --git a/src/ng2-filter.pipe.ts b/src/ng2-filter.pipe.ts index dc35ff51..60e7afef 100644 --- a/src/ng2-filter.pipe.ts +++ b/src/ng2-filter.pipe.ts @@ -30,6 +30,13 @@ export class Ng2FilterPipe { return value => { for (let key in filter) { + if (key === '$or') { + if (!this.filterByOr(filter.$or)(this.getValue(value))) { + return false; + } + continue; + } + if (!value.hasOwnProperty(key) && !Object.getOwnPropertyDescriptor(Object.getPrototypeOf(value), key)) { return false; } @@ -42,8 +49,6 @@ export class Ng2FilterPipe { isMatching = this.filterByBoolean(filter[key])(val); } else if (filterType === 'string') { isMatching = this.filterByString(filter[key])(val); - } else if (filter[key] instanceof Array && val instanceof Array) { - isMatching = this.filterByArray(filter[key])(val); } else if (filterType === 'object') { isMatching = this.filterByObject(filter[key])(val); } else { @@ -60,18 +65,27 @@ export class Ng2FilterPipe { } /** - * Filter array by array - * Match at least one value + * Filter value by $or + * * @param filter - * @returns {(value:any[])=>boolean} + * @returns {(value:any)=>boolean} */ - private filterByArray(filter: any[]) { - return (value: any[]) => { + private filterByOr(filter: any[]) { + return (value: any) => { let hasMatch = false; - const length = value.length; + const length = filter.length; + const isArray = value instanceof Array; + + const arrayComparison = (i) => { + return value.indexOf(filter[i]) !== -1; + }; + const otherComparison = (i) => { + return value === filter[i]; + }; + const comparison = isArray ? arrayComparison : otherComparison; for (let i = 0; i < length; i++) { - if (filter.indexOf(value[i]) !== -1) { + if (comparison(i)) { hasMatch = true; break; }