From 3cf1f7bd6f3722c0f7740f6b78e63c2711367e4b Mon Sep 17 00:00:00 2001 From: laura Whellans Date: Mon, 1 Feb 2016 11:14:47 +1100 Subject: [PATCH 1/2] Added capability to match on string arrays. Checking if value in searched object is an array, if true, runs matcher on each item in the array. --- demo/dist/angular-ui-tree-filter.min.js | 4 +- dist/angular-ui-tree-filter.js | 29 ++++++++- dist/angular-ui-tree-filter.min.js | 4 +- src/angular-ui-tree-filter.js | 29 ++++++++- test/unit/spec/angular-ui-tree-filter.spec.js | 63 ++++++++++++++++++- 5 files changed, 118 insertions(+), 11 deletions(-) diff --git a/demo/dist/angular-ui-tree-filter.min.js b/demo/dist/angular-ui-tree-filter.min.js index 56501e2..1e741bf 100644 --- a/demo/dist/angular-ui-tree-filter.min.js +++ b/demo/dist/angular-ui-tree-filter.min.js @@ -1,2 +1,2 @@ -/*! angular-ui-tree-filter 0.1.1, 01-10-2015 */ -!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,e,f){var g=c(d,f),h="string"==typeof g?!!g.match(new RegExp(e,a.regexFlags)):!1;return h||b(d[a.descendantCollection],e,f)}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file +/*! angular-ui-tree-filter 0.1.1, 01-02-2016 */ +!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b.forEach(function(b){b.match(a)&&(c=!0)}),c}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file diff --git a/dist/angular-ui-tree-filter.js b/dist/angular-ui-tree-filter.js index 28b3802..8ff2ee0 100644 --- a/dist/angular-ui-tree-filter.js +++ b/dist/angular-ui-tree-filter.js @@ -80,12 +80,35 @@ */ function testForField(item, pattern, address) { var value = resolveAddress(item, address); - var found = typeof value === 'string' ? - !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : - false; + var found; + if (typeof value === 'string') { + found = !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)); + } else if (Array.isArray(value)) { + found = searchStringInArray(new RegExp(pattern, uiTreeFilterSettings.regexFlags), value); + } else { + found = false; + } return found || visit(item[uiTreeFilterSettings.descendantCollection], pattern, address); } + /** + * Checks if pattern matches any of the strings in an array + * + * @param {string} str + * @param {array} strArray + * + * @returns {boolean} + */ + function searchStringInArray(str, strArray) { + var found = false; + strArray.forEach(function (item) { + if (item.match(str)) { + found = true; + } + }); + return found; + } + /** * Checks if pattern matches any of addresses * diff --git a/dist/angular-ui-tree-filter.min.js b/dist/angular-ui-tree-filter.min.js index 56501e2..1e741bf 100644 --- a/dist/angular-ui-tree-filter.min.js +++ b/dist/angular-ui-tree-filter.min.js @@ -1,2 +1,2 @@ -/*! angular-ui-tree-filter 0.1.1, 01-10-2015 */ -!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,e,f){var g=c(d,f),h="string"==typeof g?!!g.match(new RegExp(e,a.regexFlags)):!1;return h||b(d[a.descendantCollection],e,f)}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file +/*! angular-ui-tree-filter 0.1.1, 01-02-2016 */ +!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b.forEach(function(b){b.match(a)&&(c=!0)}),c}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file diff --git a/src/angular-ui-tree-filter.js b/src/angular-ui-tree-filter.js index 397ae98..95ec0c8 100755 --- a/src/angular-ui-tree-filter.js +++ b/src/angular-ui-tree-filter.js @@ -80,12 +80,35 @@ */ function testForField(item, pattern, address) { const value = resolveAddress(item, address); - const found = typeof value === 'string' ? - !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : - false; + let found; + if (typeof value === 'string') { + found = !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)); + } else if (Array.isArray(value)) { + found = searchStringInArray(new RegExp(pattern, uiTreeFilterSettings.regexFlags), value); + } else { + found = false; + } return found || visit(item[uiTreeFilterSettings.descendantCollection], pattern, address); } + /** + * Checks if pattern matches any of the strings in an array + * + * @param {string} str + * @param {array} strArray + * + * @returns {boolean} + */ + function searchStringInArray(str, strArray) { + let found = false; + strArray.forEach(function (item) { + if (item.match(str)) { + found = true; + } + }); + return found; + } + /** * Checks if pattern matches any of addresses * diff --git a/test/unit/spec/angular-ui-tree-filter.spec.js b/test/unit/spec/angular-ui-tree-filter.spec.js index 13604db..1319659 100755 --- a/test/unit/spec/angular-ui-tree-filter.spec.js +++ b/test/unit/spec/angular-ui-tree-filter.spec.js @@ -6,7 +6,7 @@ describe('Module: ui.tree-filter', function () { beforeEach(module('ui.tree-filter')); beforeEach(module(function (uiTreeFilterSettingsProvider) { - uiTreeFilterSettingsProvider.addresses = ['title']; + uiTreeFilterSettingsProvider.addresses = ['title', 'stringArray']; })); beforeEach(function () { @@ -23,6 +23,7 @@ describe('Module: ui.tree-filter', function () { { id: 21, title: '2.1. tofu-animation', + stringArray: ['item', 'match-me'], items: [ { id: 211, @@ -31,6 +32,7 @@ describe('Module: ui.tree-filter', function () { { id: 212, title: '2.1.1.1. bubble-burst', + stringArray: ['item', 'eight', 'another item'], items: [], }, ], @@ -40,6 +42,7 @@ describe('Module: ui.tree-filter', function () { { id: 22, title: '2.2. barehand-atomsplitting', + stringArray: ['find-me'], items: [], }, ], @@ -47,11 +50,13 @@ describe('Module: ui.tree-filter', function () { { id: 3, title: '3. unicorn-zapper', + stringArray: ['lowercase', 'UPPERCASE'], items: [], }, { id: 4, title: '4. romantic-transclusion', + stringArray: ['one', 'item'], items: [], }, ]; @@ -158,4 +163,60 @@ describe('Module: ui.tree-filter', function () { uiTreeFilter(sampleTree[0], matchedString); }).not.toThrow(); }); + + describe('array matching', function () { + + it('should match an array item on level 1', function () { + const matchedString = 'one'; + + expect(uiTreeFilter(sampleTree[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[1], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[2], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[3], matchedString)).toBe(true); + }); + + it('should match entire path to the first strict array match', function () { + const matchedString = 'eight'; + + expect(uiTreeFilter(sampleTree[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[0], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[0].items[0], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[0].items[0].items[0], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[1], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[2], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[3], matchedString)).toBe(false); + }); + + it('should match several items on the same level', function () { + const matchedString = '-me'; + + expect(uiTreeFilter(sampleTree[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[0], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[1].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[1], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[2], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[3], matchedString)).toBe(false); + }); + + it('should match case-insensitive', function () { + const matchedString = 'LOWERCASE'; + + expect(uiTreeFilter(sampleTree[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[0].items[0].items[0], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[1].items[1], matchedString)).toBe(false); + expect(uiTreeFilter(sampleTree[2], matchedString)).toBe(true); + expect(uiTreeFilter(sampleTree[3], matchedString)).toBe(false); + }); + + }); }); From d6ec13368b03a4a4a5aa58bf4d359f72da7b811a Mon Sep 17 00:00:00 2001 From: laura Whellans Date: Fri, 5 Feb 2016 13:28:16 +1100 Subject: [PATCH 2/2] Added check for array --- demo/dist/angular-ui-tree-filter.min.js | 4 ++-- dist/angular-ui-tree-filter.js | 14 ++++++++------ dist/angular-ui-tree-filter.min.js | 4 ++-- src/angular-ui-tree-filter.js | 14 ++++++++------ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/demo/dist/angular-ui-tree-filter.min.js b/demo/dist/angular-ui-tree-filter.min.js index 1e741bf..c6b5113 100644 --- a/demo/dist/angular-ui-tree-filter.min.js +++ b/demo/dist/angular-ui-tree-filter.min.js @@ -1,2 +1,2 @@ -/*! angular-ui-tree-filter 0.1.1, 01-02-2016 */ -!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b.forEach(function(b){b.match(a)&&(c=!0)}),c}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file +/*! angular-ui-tree-filter 0.1.1, 05-02-2016 */ +!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b?(b.forEach(function(b){b.match(a)&&(c=!0)}),c):void 0}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file diff --git a/dist/angular-ui-tree-filter.js b/dist/angular-ui-tree-filter.js index 8ff2ee0..3f9ba89 100644 --- a/dist/angular-ui-tree-filter.js +++ b/dist/angular-ui-tree-filter.js @@ -101,12 +101,14 @@ */ function searchStringInArray(str, strArray) { var found = false; - strArray.forEach(function (item) { - if (item.match(str)) { - found = true; - } - }); - return found; + if (strArray) { + strArray.forEach(function (item) { + if (item.match(str)) { + found = true; + } + }); + return found; + } } /** diff --git a/dist/angular-ui-tree-filter.min.js b/dist/angular-ui-tree-filter.min.js index 1e741bf..c6b5113 100644 --- a/dist/angular-ui-tree-filter.min.js +++ b/dist/angular-ui-tree-filter.min.js @@ -1,2 +1,2 @@ -/*! angular-ui-tree-filter 0.1.1, 01-02-2016 */ -!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b.forEach(function(b){b.match(a)&&(c=!0)}),c}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file +/*! angular-ui-tree-filter 0.1.1, 05-02-2016 */ +!function(a){"use strict";a.module("ui.tree-filter",[]).provider("uiTreeFilterSettings",function(){var a=this;this.addresses=["title"],this.regexFlags="gi",this.descendantCollection="items",this.$get=function(){return{addresses:a.addresses,regexFlags:a.regexFlags,descendantCollection:a.descendantCollection}}}).filter("uiTreeFilter",["uiTreeFilterSettings",function(a){function b(a,b,c){a=a||[];var e=!1;return a.forEach(function(a){e=e||d(a,b,c)}),e}function c(a,b){var d=b.split(".");if(void 0!==a)return d.length<2?a[d[0]]:c(a[d[0]],d.slice(1).join("."))}function d(d,f,g){var h,i=c(d,g);return h="string"==typeof i?!!i.match(new RegExp(f,a.regexFlags)):Array.isArray(i)?e(new RegExp(f,a.regexFlags),i):!1,h||b(d[a.descendantCollection],f,g)}function e(a,b){var c=!1;return b?(b.forEach(function(b){b.match(a)&&(c=!0)}),c):void 0}return function(b,c,e){return e=e||a.addresses,void 0===c||e.reduce(function(a,e){return a||d(b,c,e)},!1)}}])}(angular); \ No newline at end of file diff --git a/src/angular-ui-tree-filter.js b/src/angular-ui-tree-filter.js index 95ec0c8..7be2e03 100755 --- a/src/angular-ui-tree-filter.js +++ b/src/angular-ui-tree-filter.js @@ -101,12 +101,14 @@ */ function searchStringInArray(str, strArray) { let found = false; - strArray.forEach(function (item) { - if (item.match(str)) { - found = true; - } - }); - return found; + if (strArray) { + strArray.forEach(function (item) { + if (item.match(str)) { + found = true; + } + }); + return found; + } } /**