HGB
HGB

Reputation: 2193

Filtering from to letter in Angular

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

Answers (2)

sheilak
sheilak

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;
};

JSFiddle

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

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;
  };
});

Working PLunkr

Upvotes: 1

Related Questions