Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter ng-repeat elements from the beginning of the string

I'm experimenting with AngularJS, this is my first try. I'm trying to filter an array of objects using something like "starts with" rather than "contains", but I'm not understanding how to do that.

Let's say that I have an elements array like this

[{
  amount: 50
}, {
  amount: 25
}]

If I want to filter by 5 both records will be shown, while I just want to have the first one, the one that starts with 5.

This is what I've done so far, for the looping part (I've also added the ordering and paging part, even if maybe isn't influencing what I'm trying to achieve)

<tr ng-repeat="element in elements | filter:search:strict | orderBy:predicate:reverse | filter:startFrom:currentPage*pageSize | limitTo:pageSize">
  <td>{{element.name}}</td>
  <td>{{hotel.amount}}</td>
</tr>

and for the input where I write the "5"

<input class="pull-right" ng-model="search.amount">

I'm not understanding how to create a custom handler here, so that I can parse each nth item and see if it starts with the passed number.

like image 749
Alberto Zaccagni Avatar asked Nov 24 '13 19:11

Alberto Zaccagni


People also ask

How do I filter in NG-repeat?

The ng-repeat values can be filtered according to the ng-model in AngularJS by using the value of the input field as an expression in a filter. We can set the ng-model directive on an input field to filter ng-repeat values.

How do I get the index of an element in NG-repeat?

Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.

What can I use instead of NG-repeat?

You can consider using transclusion inside a custom directive, to achieve the behavior you are looking for without using ng-repeat.

What is Ng-repeat explain with example?

Definition and Usage The ng-repeat directive repeats a set of HTML, a given number of times. The set of HTML will be repeated once per item in a collection. The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item.


2 Answers

I would just write basic custom filter:

JS

var iApp = angular.module("App", []);

 iApp.filter('myfilter', function() {

   function strStartsWith(str, prefix) {
    return (str+"").indexOf(prefix) === 0;
   }


   return function( items, amount) {


    var filtered = [];

    angular.forEach(items, function(item) {
      if(strStartsWith(item.amount, amount)){
        filtered.push(item);
      }
    });

    return filtered;
  };
});

    iApp.controller('TestController', function($scope)
    {   
       $scope.amount='';

       $scope.elements = [
         { amount: 50},
         { amount: 25 }];                
     }); 

HTML

<body data-ng-controller="TestController">

  <input class="pull-right" ng-model="amount">

        <table id="hotels">
            <tr data-ng-repeat="element in elements | myfilter:amount">
                <td>{{element.amount}}</td>
            </tr>
        </table>
        <br/>

    </body>

Demo Plunker

like image 87
Maxim Shoustin Avatar answered Oct 22 '22 21:10

Maxim Shoustin


Maxim's answer helped me, but I thought I'd chip in with a slightly more general solution for filtering either a flat list or a list of objects where you want to filter on a specific property.

View Plunkr

/**
 * Filter a list for elements with start with the given string.
 * 
 * @param {Array} items - The list of items to filter
 * @param {String} prefix - The prefix to search for
 * @param {String} [itemProperty] - An optional property to use for the search
 *                                  if filtering a list of objects.
 */
.filter('startsWith', function() {
  return function(items, prefix, itemProperty) {
    return items.filter(function(item) {
      var findIn = itemProperty ? item[itemProperty] : item;
      return findIn.toString().indexOf(prefix) === 0;
    });
  };
})

Example Usage

// item in flatList | startswith:<term>
var flatList = ['foo', 'bar', 'zulu']

// item in objectList | startswith:<term>:<key>
var objectList = [
  {value: 'foo', label: '-FOO-'},
  {value: 'bar', label: '-BAR-'}
];

To make case insensitive just apply .toLowerCase() to both the prefix and to findIn

like image 34
Ian Clark Avatar answered Oct 22 '22 21:10

Ian Clark