Reputation: 2193
I have been through a few of those questions on Stackoverflow and found this link from a thread:http://toddmotto.com/everything-about-custom-filters-in-angular-js/ which is great but I am struggling to adapt it to what I need to do.
I am trying to implement a simple function based on it which will have a button group one which shows all results then from and to letter such as:
<button type="button" class="btn btn-primary">All</button>
<button type="button" class="btn btn-primary”>A-E</button>
<button type="button" class="btn btn-primary">F-K</button>
<button type="button" class="btn btn-primary">L-P</button>
However I am unable to adapt the function to perform this filter. I can only do with the basic filter by single letter.
<button type="button" class="btn btn-primary" ng-click="letter = 'C'">C</button>
I am also unable to show “all results" Here is my app code:
var app = angular.module (‘app', []);
app.controller('PersonCtrl', function () {
this.friends = [{
name: 'Andrew'
},
{
name: 'Bob'
},{
name: 'Beano'
},{
name: 'Chris'
}, {
name: 'Will'
}, {
name: 'Mark'
}, {
name: 'Alice'
}, {
name: 'Todd'
}];
});
app.filter('startsWithLetter', function () {
return function (items, letter) {
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.name.substring(0, 1))) {
filtered.push(item);
}
}
return filtered;
};
});
HTML CONTROLLER CODE:
<div class="container" ng-controller="PersonCtrl as person">
<ul>
<li ng-repeat="friend in person.friends | startsWithLetter:letter">
{{ friend }}
</li>
</ul>
</div>
How do I adapt this to perform more specific filtering?
Upvotes: 1
Views: 2020
Reputation: 5873
You can use colons to pass multiple arguments to your filter - fromLetter
and toLetter
as well as your input.
<li ng-repeat="friend in person.friends | startsWithLetter:person.fromLetter:person.toLetter">
{{ friend }}
</li>
Then you can lowercase the first letter of the string and compare this directly to fromLetter
and toLetter
app.filter('startsWithLetter', function () {
return function (items, fromLetter, toLetter) {
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
var firstLetter = item.name.substring(0, 1).toLowerCase();
if ((!fromLetter || firstLetter >= fromLetter)
&& (!toLetter || firstLetter <= toLetter)) {
filtered.push(item);
}
}
return filtered;
};
});
That means that the button logic needs to be slightly more complex and set two variables:
<button type="button" class="btn btn-primary" ng-click="person.setLetters()">All</button>
<button type="button" class="btn btn-primary" ng-click="person.setLetters('a','e')">A-E</button>
<button type="button" class="btn btn-primary" ng-click="person.setLetters('f','k')">F-K</button>
<button type="button" class="btn btn-primary" ng-click="person.setLetters('l','p')">L-P</button>
and on your controller:
this.setLetters = function(from, to){
this.fromLetter = from;
this.toLetter = to;
};
Upvotes: 1
Reputation: 136154
You could have filtering based on the alphabet ASCII
codes. On button click set the range of ASCII
code using ng-click
directive with -
separated value like letter='65-69
. Then that range will pass through the the filter, out of which first parameter is upperLimit
& 2nd one is lowerLimit
of the selected range. For comparing the starting variable ASCII
value we could use string.charCodeAt('0')
method which will return ASCII value of first character & will compare that value with the range variable inside foreach loop.
Markup
<div class="container" ng-controller="PersonCtrl as person">
<ul>
<li ng-repeat="friend in person.friends | startsWithLetter:letter">
{{ friend }}
</li>
</ul>
<button type="button" class="btn btn-primary" ng-click="letter=''">All</button>
<button type="button" class="btn btn-primary" ng-click="letter='65-69'">A-E</button>
<button type=" button " class="btn btn-primary" ng-click="letter='70-75'">F-K</button>
<button type="button " class="btn btn-primary " ng-click="letter='76-80'">L-P</button>
</div>
Filter
app.filter('startsWithLetter', function() {
return function(items, letter) {
if (!letter || letter.length == 0)
return items;
var filtered = [],
range = letter.split('-');
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
for (var j = parseInt(range[0]); j <= parseInt(range[1]); j++) {
if (item.name.charCodeAt('0') == j) {
filtered.push(item);
}
}
}
return filtered;
};
});
Upvotes: 1