Robert Lee Robert Lee - 1 month ago 15
AngularJS Question

AngularJS Smart Table filtering special characters with a space when displaying all rows

I am running a few tables that use the pipe/ajax section of the code with the controller/service setup. https://lorenzofox3.github.io/smart-table-website/#section-pipe

One of the issues I am coming across is when there are special characters in the values with a space in it and it is unable to filter it. For example, if there was a lastname of "last-name firstname" it is unable to filter the data but it is able to filter the name "last-name" and it is able to do "lastname firstname" just fine.

Could I get some help on figuring out why this might not be able to filter correctly?

Thank You!

Edit: I noticed I forgot to add the filter.

app.filter('propsFilter', function() {
return function(items, props) {
var out = [];

if (angular.isArray(items)) {
var keys = Object.keys(props);

items.forEach(function(item) {
var itemMatches = false;

for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
break;
}
}

if (itemMatches) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}

return out;
};
});

app.controller('mainCtrl', ['$scope', '$window', 'Resource', function($scope, $window, service) {

var ctrl = this;

this.displayed = [];

$scope.itemsByPage = $window.datatableperPage;

this.callServer = function callServer(tableState) {

ctrl.isLoading = true;

var pagination = tableState.pagination;

var start = pagination.start || 0;
var number = pagination.number || 10;

service.getPage(start, number, tableState).then(function(result) {
ctrl.displayed = result.data;
tableState.pagination.numberOfPages = result.numberOfPages; //set the number of pages so the pagination can update
ctrl.isLoading = false;
});
};

}]);
app.factory('Resource', ['$q', '$filter', '$window', '$http', '$timeout', function($q, $filter, $window, $http, $timeout) {

var nameData = [];

$http.get($window.datatableSource).success(function(response) {
nameData = response;
});

function getPage(start, number, params) {

var deferred = $q.defer();

var filtered = params.search.predicateObject ? $filter('filter')(nameData, params.search.predicateObject) : nameData;

if (params.sort.predicate) {
filtered = $filter('orderBy')(filtered, params.sort.predicate, params.sort.reverse);
}

var result = filtered.slice(start, start + number);

$timeout(function() {
//note, the server passes the information about the data set size
deferred.resolve({
data: result,
numberOfPages: Math.ceil(filtered.length / number),
});
}, $window.datatableTimeout);

return deferred.promise;
}

return {
getPage: getPage
};


}]);


Update:

With Hardy's Help I was finally able to replicate the issue.

When setting the

$scope.itemsByPage = -1;


the filtered results seem to vanish after initial couple characters at the slice

result = filtered.slice(start, start + number);


In this example, I added the word "Clinical - " to the beginning of a name and it is unable to search for the word when you start typing the word "Clinical" but other words work just fine.

https://plnkr.co/edit/7n68AKbwQGpVdFOpbUuP?p=preview

Answer

Okay, I've traced all the functions and the problem in Plunker is in this very line. Try to change the value to any positive integer and you will see that your app works just fine.

$scope.itemsByPage = -1;

The reason you get strange filtering results in some cases is because this very value is used as number later in

var result = filtered.slice(start, start + number);

thus translating to

var result = filtered.slice(0, -1);

.slice(0, -1) returns a shallow copy of the filtered array excluding the last item. And when you only have one filtered result you will recieve an empty array.

VoilĂ !