Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demo/dist/angular-ui-tree-filter.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 28 additions & 3 deletions dist/angular-ui-tree-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,37 @@
*/
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;
if (strArray) {
strArray.forEach(function (item) {
if (item.match(str)) {
found = true;
}
});
return found;
}
}

/**
* Checks if pattern matches any of addresses
*
Expand Down
4 changes: 2 additions & 2 deletions dist/angular-ui-tree-filter.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 28 additions & 3 deletions src/angular-ui-tree-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,37 @@
*/
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please declare explicitly that strArray has to be an array of strings: string[] or (preferably) Array.<string>.
Otherwise the function does not do what it claims to do

*
* @returns {boolean}
*/
function searchStringInArray(str, strArray) {
let found = false;
if (strArray) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check does not seem to be necessary: this function is only used in a context where the 2nd argument is pre-ensured to be an array.

strArray.forEach(function (item) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lalooola please use Array#some here. This will improve performance of large arrays.
Array#some stops iterating after its callback returns true for the first time. And it returns boolean itself so there's no need for intermediate variable

if (item.match(str)) {
found = true;
}
});
return found;
}
}

/**
* Checks if pattern matches any of addresses
*
Expand Down
63 changes: 62 additions & 1 deletion test/unit/spec/angular-ui-tree-filter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand All @@ -23,6 +23,7 @@ describe('Module: ui.tree-filter', function () {
{
id: 21,
title: '2.1. tofu-animation',
stringArray: ['item', 'match-me'],
items: [
{
id: 211,
Expand All @@ -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: [],
},
],
Expand All @@ -40,18 +42,21 @@ describe('Module: ui.tree-filter', function () {
{
id: 22,
title: '2.2. barehand-atomsplitting',
stringArray: ['find-me'],
items: [],
},
],
},
{
id: 3,
title: '3. unicorn-zapper',
stringArray: ['lowercase', 'UPPERCASE'],
items: [],
},
{
id: 4,
title: '4. romantic-transclusion',
stringArray: ['one', 'item'],
items: [],
},
];
Expand Down Expand Up @@ -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);
});

});
});