Fix/Feature: Tokenizer improved to support flags and files missed in last commit updated.
This commit is contained in:
parent
fb8e217c81
commit
e8f4931d29
|
@ -1,8 +1,47 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var AccountListCtrl = ['$scope', 'accounts', function ($scope, accounts) {
|
var AccountListCtrl = ['$scope', '$location', '$routeParams', 'Tokenizer', 'accounts', function ($scope, $location, $routeParams, Tokenizer, accounts) {
|
||||||
|
$scope.search = $routeParams.q || '';
|
||||||
$scope.info = accounts;
|
$scope.info = accounts;
|
||||||
}];
|
|
||||||
|
$scope.$watch('search', function (value) {
|
||||||
|
$scope.filterAccounts(value);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
$scope.searchInfo = {
|
||||||
|
comparator: {
|
||||||
|
'def': 'n',
|
||||||
|
'n': {'Col': 'Name', 'Comparator': 'text'},
|
||||||
|
't': {'Col': 'Type', 'Comparator': 'text'},
|
||||||
|
'a': {'Col': 'IsActive', 'Comparator': 'boolean'},
|
||||||
|
'r': {'Col': 'IsReconcilable', 'Comparator': 'boolean'},
|
||||||
|
'c': {'Col': 'CostCenter', 'Comparator': 'text'}
|
||||||
|
},
|
||||||
|
sorter: {
|
||||||
|
'n': 'Name',
|
||||||
|
't': 'Type',
|
||||||
|
'a': 'IsActive',
|
||||||
|
'r': 'IsReconcilable',
|
||||||
|
'c': 'CostCenter'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.filterAccounts = _.debounce(function (q) {
|
||||||
|
if (q !== $scope._search) {
|
||||||
|
$scope._search = q;
|
||||||
|
if (angular.isUndefined(q) || q === '') {
|
||||||
|
$location.path('/Accounts').search('q', null).replace();
|
||||||
|
} else {
|
||||||
|
$location.path('/Accounts').search({'q': q}).replace();
|
||||||
|
}
|
||||||
|
$scope.$apply(function () {
|
||||||
|
var matches = Tokenizer.parseFilterString(q, $scope.searchInfo);
|
||||||
|
$scope.accounts = Tokenizer.doFilter('/Accounts ' + q, $scope.info, matches);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 350);
|
||||||
|
}]
|
||||||
|
;
|
||||||
AccountListCtrl.resolve = {
|
AccountListCtrl.resolve = {
|
||||||
accounts: ['Account', function (Account) {
|
accounts: ['Account', function (Account) {
|
||||||
return Account.query({}).$promise;
|
return Account.query({}).$promise;
|
||||||
|
|
|
@ -234,3 +234,75 @@ overlord_service.service('EventSource', function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
overlord_service.factory('Tokenizer', ['$filter', function ($filter) {
|
||||||
|
var parseFilterString = function (q, searchInfo) {
|
||||||
|
var re = /((([^ ]+):\s*('[^':]+'|"[^":]+"|[^ ]+))|[^ ]+[^: '"]*)/g,
|
||||||
|
comparator = searchInfo.comparator,
|
||||||
|
sorter = searchInfo.sorter,
|
||||||
|
defaultKey = comparator[comparator.def],
|
||||||
|
matches = [],
|
||||||
|
sorting = [],
|
||||||
|
flags = {};
|
||||||
|
|
||||||
|
|
||||||
|
function isTrue(value) {
|
||||||
|
return !_.any(['f', 'fa', 'fal', 'fals', 'false', 'n', 'no', '0'], function (item) {
|
||||||
|
return item === value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushObject(comparator, value) {
|
||||||
|
return {'Col': comparator.Col, 'Comparator': comparators[comparator.Comparator], 'Value': value};
|
||||||
|
}
|
||||||
|
|
||||||
|
var comparators = {
|
||||||
|
'text': function (obj, text) {
|
||||||
|
return obj.toLowerCase().indexOf(text) > -1;
|
||||||
|
},
|
||||||
|
'boolean': function (obj, text) {
|
||||||
|
return obj === isTrue(text);
|
||||||
|
},
|
||||||
|
'true': function (obj, text) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var m = q.match(re);
|
||||||
|
_.forEach(m, function (item) {
|
||||||
|
item = item.trim();
|
||||||
|
if (item.indexOf(':') === -1) {
|
||||||
|
if ((item.length > 1) && (item.charAt(0) === '+' || item.charAt(0) === '-') && (item.substr(1) in sorter)) {
|
||||||
|
sorting.push(item.charAt(0) + sorter[item.substr(1).toLowerCase()]);
|
||||||
|
} else if (item.length >= 1 && item.charAt(0) !== '+' && item.charAt(0) !== '-') {
|
||||||
|
matches.push(pushObject(defaultKey, item));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var key = item.substr(0, item.indexOf(':')).toLowerCase();
|
||||||
|
var value = item.substr(item.indexOf(':') + 1, item.length).trim().toLowerCase();
|
||||||
|
if (value.indexOf("'") !== -1 || value.indexOf('"') !== -1) {
|
||||||
|
value = value.substring(1, value.length - 1).trim();
|
||||||
|
}
|
||||||
|
if (key !== '' && value !== '' && key in comparator) {
|
||||||
|
matches.push(pushObject(comparator[key], value));
|
||||||
|
} else if (key !== '' && key in searchInfo.flags) {
|
||||||
|
flags[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {'q': matches, 'o': sorting, 'f': flags};
|
||||||
|
};
|
||||||
|
var doFilter = _.memoize(function (q, array, matches) {
|
||||||
|
var filterExpressions = matches.q,
|
||||||
|
sortPredicates = matches.o,
|
||||||
|
filterCount = filterExpressions.length;
|
||||||
|
var arrayCopy = filterCount === 0 ? array : _.filter(array, function (item) {
|
||||||
|
return _.every(filterExpressions, function (expression) {
|
||||||
|
return expression.Comparator(item[expression.Col], expression.Value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
arrayCopy = sortPredicates.length === 0 ? arrayCopy : $filter('orderBy')(arrayCopy, sortPredicates);
|
||||||
|
return arrayCopy;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {'parseFilterString': parseFilterString, 'doFilter': doFilter };
|
||||||
|
}]);
|
|
@ -9,20 +9,28 @@ var ProductListCtrl = ['$scope', '$location', '$routeParams', 'Tokenizer', 'prod
|
||||||
$scope.filterProducts(newValue);
|
$scope.filterProducts(newValue);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
$scope.comparator = {
|
$scope.searchInfo = {
|
||||||
|
comparator: {
|
||||||
'def': 'n',
|
'def': 'n',
|
||||||
'n': {'Col': 'Name', 'Comparator': 'text'},
|
'n': {'Col': 'Name', 'Comparator': 'text'},
|
||||||
'a': {'Col': 'IsActive', 'Comparator': 'boolean'},
|
'a': {'Col': 'IsActive', 'Comparator': 'boolean'},
|
||||||
'u': {'Col': 'Units', 'Comparator': 'text'},
|
'u': {'Col': 'Units', 'Comparator': 'text'},
|
||||||
't': {'Col': 'ProductGroup', 'Comparator': 'text'}
|
't': {'Col': 'ProductGroup', 'Comparator': 'text'}
|
||||||
};
|
},
|
||||||
$scope.sorter = {
|
sorter: {
|
||||||
'c': 'Code',
|
'c': 'Code',
|
||||||
'n': 'Name',
|
'n': 'Name',
|
||||||
'u': 'Units',
|
'u': 'Units',
|
||||||
'p': 'Price',
|
'p': 'Price',
|
||||||
't': 'ProductGroup',
|
't': 'ProductGroup',
|
||||||
'a': 'IsActive'
|
'a': 'IsActive',
|
||||||
|
'y': 'ProductYield',
|
||||||
|
'f':'Fraction',
|
||||||
|
'fu': 'FractionUnits'
|
||||||
|
},
|
||||||
|
flags: {
|
||||||
|
'e': 'boolean'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.filterProducts = _.debounce(function (q) {
|
$scope.filterProducts = _.debounce(function (q) {
|
||||||
|
@ -34,11 +42,8 @@ var ProductListCtrl = ['$scope', '$location', '$routeParams', 'Tokenizer', 'prod
|
||||||
$location.path('/Products').search({'q': q}).replace();
|
$location.path('/Products').search({'q': q}).replace();
|
||||||
}
|
}
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
var matches = Tokenizer.parseFilterString(q, $scope.comparator, $scope.sorter);
|
var matches = Tokenizer.parseFilterString(q, $scope.searchInfo);
|
||||||
$scope.show_extended = _.any(matches.q, function (item) {
|
$scope.show_extended = 'e' in matches.f;
|
||||||
return ((item.key === 'e' || item.key === 'ext') && $scope.isTrue(item.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.products = Tokenizer.doFilter('/Products ' + q, $scope.info, matches);
|
$scope.products = Tokenizer.doFilter('/Products ' + q, $scope.info, matches);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue