|
10 | 10 |
|
11 | 11 | const uiTreeFilterSettings = this; |
12 | 12 |
|
13 | | - this.supportedFields = ['title']; |
| 13 | + this.addresses = ['title']; |
14 | 14 | this.regexFlags = 'gi'; |
15 | | - this.descendantCollectionField = 'items'; |
| 15 | + this.descendantCollection = 'items'; |
16 | 16 |
|
17 | 17 | this.$get = function () { |
18 | 18 | return { |
19 | | - supportedFields: uiTreeFilterSettings.supportedFields, |
| 19 | + addresses: uiTreeFilterSettings.addresses, |
20 | 20 | regexFlags: uiTreeFilterSettings.regexFlags, |
21 | | - descendantCollectionField: uiTreeFilterSettings.descendantCollectionField, |
| 21 | + descendantCollection: uiTreeFilterSettings.descendantCollection, |
22 | 22 | }; |
23 | 23 | }; |
24 | 24 | }) |
|
31 | 31 | * Iterates through given collection if flag is not true and sets a flag to true on first match. |
32 | 32 | * |
33 | 33 | * @param {Array} collection |
34 | | - * @param {string} fieldName |
35 | 34 | * @param {string} pattern |
36 | | - * @param {boolean} flag |
| 35 | + * @param {string} address |
| 36 | + * |
37 | 37 | * @returns {boolean} |
38 | 38 | */ |
39 | | - function visit(collection, pattern, fieldName, flag) { |
40 | | - flag = flag || false; |
41 | | - if (!flag && collection) { |
42 | | - collection.forEach(function (collectionItem) { |
43 | | - flag = flag ? true : testForField(collectionItem, fieldName, pattern); |
44 | | - }); |
45 | | - } |
46 | | - return flag; |
| 39 | + function visit(collection, pattern, address) { |
| 40 | + collection = collection || []; |
| 41 | + let foundSoFar = false; |
| 42 | + |
| 43 | + collection.forEach(function (collectionItem) { |
| 44 | + foundSoFar = foundSoFar || testForField(collectionItem, pattern, address); |
| 45 | + }); |
| 46 | + |
| 47 | + return foundSoFar; |
| 48 | + } |
| 49 | + |
| 50 | + /** |
| 51 | + * Resolves object value from dot-delimited address. |
| 52 | + * |
| 53 | + * @param object |
| 54 | + * @param path |
| 55 | + * @returns {*} |
| 56 | + */ |
| 57 | + function resolveAddress(object, path) { |
| 58 | + const parts = path.split('.'); |
| 59 | + return parts.length < 2 ? object[parts[0]] : resolveAddress(object[parts[0]], parts.slice(1).join('.')); |
47 | 60 | } |
48 | 61 |
|
49 | 62 | /** |
50 | 63 | * Checks if object or its children matches a pattern on a given field |
51 | 64 | * |
52 | | - * @param {object} item |
| 65 | + * First it resolves the property address and gets the value. |
| 66 | + * If the value is a string it matches it against provided pattern. |
| 67 | + * If item matches because its property matches it's children are not checked. |
| 68 | + * Otherwise all item descendants are checked as well |
| 69 | + * |
| 70 | + * @param {Object} item |
53 | 71 | * @param {string} pattern |
54 | | - * @param {string} fieldName |
| 72 | + * @param {string} address property name or dot-delimited path to property. |
55 | 73 | * |
56 | 74 | * @returns {boolean} |
57 | 75 | */ |
58 | | - function testForField(item, pattern, fieldName) { |
59 | | - const foundInField = item[fieldName] ? |
60 | | - !!item[fieldName].match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : |
| 76 | + function testForField(item, pattern, address) { |
| 77 | + const value = resolveAddress(item, address); |
| 78 | + const found = typeof value === 'string' ? |
| 79 | + !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : |
61 | 80 | false; |
62 | | - |
63 | | - return visit(item[uiTreeFilterSettings.descendantCollectionField], fieldName, pattern, foundInField); |
| 81 | + return found || visit(item[uiTreeFilterSettings.descendantCollection], pattern, address); |
64 | 82 | } |
65 | 83 |
|
66 | 84 | /** |
67 | | - * Checks if pattern matches any of supported fields |
| 85 | + * Checks if pattern matches any of addresses |
68 | 86 | * |
69 | 87 | * @param {object} item |
70 | 88 | * @param {string} pattern |
71 | 89 | * |
72 | 90 | * @returns {boolean} |
73 | 91 | */ |
74 | | - return function (item, pattern, supportedFields) { |
75 | | - supportedFields = supportedFields || uiTreeFilterSettings.supportedFields; |
76 | | - return supportedFields.reduce(function (foundInAnyField, fieldName) { |
77 | | - return foundInAnyField ? true : testForField(item, pattern, fieldName); |
| 92 | + return function (item, pattern, addresses) { |
| 93 | + addresses = addresses || uiTreeFilterSettings.addresses; |
| 94 | + return pattern === undefined || addresses.reduce(function (foundSoFar, fieldName) { |
| 95 | + return foundSoFar || testForField(item, pattern, fieldName); |
78 | 96 | }, false); |
79 | 97 | }; |
80 | 98 | }); |
|
0 commit comments