UNPKG

angular-ui-tree-filter

Version:

A module providing an AngularJS filter which can be used with angular-ui-tree to match tree nodes

105 lines (93 loc) 3.82 kB
(function (angular) { 'use strict'; angular.module('ui.tree-filter', []) /** * @ngdoc object * @name ui.tree-filter.provider:uiTreeFilterSettings */ .provider('uiTreeFilterSettings', function () { var uiTreeFilterSettings = this; this.addresses = ['title']; this.regexFlags = 'gi'; this.descendantCollection = 'items'; this.$get = function () { return { addresses: uiTreeFilterSettings.addresses, regexFlags: uiTreeFilterSettings.regexFlags, descendantCollection: uiTreeFilterSettings.descendantCollection, }; }; }) /** * @ngdoc function * @name ui.tree-filter.factory:uiTreeFilter */ .filter('uiTreeFilter', ["uiTreeFilterSettings", function (uiTreeFilterSettings) { /** * Iterates through given collection if flag is not true and sets a flag to true on first match. * * @param {Array} collection * @param {string} pattern * @param {string} address * * @returns {boolean} */ function visit(collection, pattern, address) { collection = collection || []; var foundSoFar = false; collection.forEach(function (collectionItem) { foundSoFar = foundSoFar || testForField(collectionItem, pattern, address); }); return foundSoFar; } /** * Resolves object value from dot-delimited address. * * @param object * @param path * @returns {*} */ function resolveAddress(object, path) { var parts = path.split('.'); if (object === undefined) { return; } return parts.length < 2 ? object[parts[0]] : resolveAddress(object[parts[0]], parts.slice(1).join('.')); } /** * Checks if object or its children matches a pattern on a given field * * First it resolves the property address and gets the value. * If the value is a string it matches it against provided pattern. * If item matches because its property matches it's children are not checked. * Otherwise all item descendants are checked as well * * @param {Object} item * @param {string} pattern * @param {string} address property name or dot-delimited path to property. * * @returns {boolean} */ function testForField(item, pattern, address) { var value = resolveAddress(item, address); var found = typeof value === 'string' ? !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : false; return found || visit(item[uiTreeFilterSettings.descendantCollection], pattern, address); } /** * Checks if pattern matches any of addresses * * @param {object} item * @param {string} pattern * * @returns {boolean} */ return function (item, pattern, addresses) { addresses = addresses || uiTreeFilterSettings.addresses; return pattern === undefined || addresses.reduce(function (foundSoFar, fieldName) { return foundSoFar || testForField(item, pattern, fieldName); }, false); }; }]); })(angular);