Filter for number range : AngularJS

15,739

Solution 1

You could write a custom filter function that filter by range on a particular field:

$scope.byRange = function (fieldName, minValue, maxValue) {
  if (minValue === undefined) minValue = Number.MIN_VALUE;
  if (maxValue === undefined) maxValue = Number.MAX_VALUE;

  return function predicateFunc(item) {
    return minValue <= item[fieldName] && item[fieldName] <= maxValue;
  };
};

and use it in ng-repeat expression:

<div ng-repeat="formElement in formElements | filter:byRange('age', filterModelMin.age, filterModelMax.age)">

Note that the filterModelMin.age and filterModelMax.age can be used directly in fasterDisplay directive because both fasterForm and fasterDisplay do not have their own scope.

Example plunker: http://plnkr.co/edit/dFbBCKxSxm9RI9dwSeYR?p=preview

Solution 2

You can do this using a custom filter select function. In your repeat you can do:

<div  ng-repeat = "formElement in formElements | filter:filterAge">

And the following function in your controller:

$scope.filterAge = function(val) {
  return (val.age > MIN_AGE && val.age < MAX_AGE);
};

However, in your case you have the required values (MIN_AGE and MAX_AGE) in a different directive and in a different scope. You could share this values to the correct directive by either using a service or storing the values in the parent scope and passing the reference into your directives.

Solution 3

To expand on runTarm's answer. This will allow you to use nested values with the dot operator:

$scope.byRange = function (fieldName, minValue, maxValue) {
  if (minValue === undefined) minValue = Number.MIN_VALUE;
  if (maxValue === undefined) maxValue = Number.MAX_VALUE;

  return function predicateFunc(item) {
    var keys = fieldName.split('.');
    var val = item;
    for (var i = 0; i < keys.length; i++) {
      val = val[keys[i]];
    }

    return minValue <= val && val <= maxValue;
  };
};

used in your ng-repeat expression like so:

<div ng-repeat="formElement in formElements | filter:byRange('person.age', filterModelMin.age, filterModelMax.age)">
Share:
15,739
Anand
Author by

Anand

Updated on June 09, 2022

Comments

  • Anand
    Anand almost 2 years

    I have a form with some input types like text, radio etc. When I submit the form, it lists the entered details below the form(used template and directive for this). I want to do filter in age , ie, the number input type, such that when I give an age range, it should filter profiles with corresponding age range. Here is the plunker :

    http://plnkr.co/edit/h8p8rtZuAhCoKClUjgE9?p=preview

        <table border="1" style="width:200px">
       <tr>
           <td> <div>Name : {{  formElement.name }} </div><br> </td> 
       </tr>
       <tr>
           <td> <div>Age : {{ formElement.age }}</div><br> </td>
       </tr>
    
  • MadsMadsDk
    MadsMadsDk over 9 years
    Am I able to use this function if I have an object containing all my filters? I'm writing an app where I'll have to filter on location and agerange, and possibly more filters. How would I go about doing this? My object looks like this: $scope.eventsfilter = {minAge: <numberrange>, maxAge: <numberrange>, postal: <string>} - so both the minAge and maxAge should match the range the user defines. (So if a user wants to filter events from age 21-27, it also matches events for age 22-24).