slevin
slevin

Reputation: 3886

angular.js filter has dynamic and default value

This is my code, based here. limitTo is dynamic and gets its value from user input.

<script>
   var monthly=[123.659855, 89.645222, 97.235644, 129.555555];
   function MyFilterDemoCtrl($scope) {$scope.monthly= monthly;};
</script>

<body ng-controller="MyFilterDemoCtrl" >
 Num: <input ng-model="num" type="text" />
 <li ng-repeat="gigabytes in monthly | limitTo:num"> {{ gigabytes}} </li>
<body>

I was wondering how can I alter the limitTo filter like this

<li ng-repeat="gigabytes in monthly | limitTo:monthly.lenght() OR num">

so when the page loads (input is empty) all the items of the array are displayed and when user types a number, the proper amount of items is displayed.

(page loads, all items displayed, then user types 3, only the first 3 items appear)

To make it "perfect" I would like to know how I can print a message to the user when the input exceeds the array lenght.

Thanks in advance

EDIT

Code as it is now , cannot display all items, and then redisplay user input. The only way to display all when page loads is to do

gigabytes in monthly track by $index | limitTo:num

but then the user input has no effect. I use angular 1.2.28. I dont actually get the concept of track by $index. Thanks again

Upvotes: 1

Views: 355

Answers (3)

Martin
Martin

Reputation: 16300

How about this:

var monthly = [123.659855, 89.645222, 97.235644, 129.555555];

function MyFilterDemoCtrl($scope) {
  
  $scope.monthly = monthly;
  
  $scope.limit = function() {
  
    return $scope.num || $scope.monthly.length;
  }
}

angular.module('app', [])
  .controller('MyFilterDemoCtrl', MyFilterDemoCtrl);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="MyFilterDemoCtrl">  
  
  Num: <input ng-model="num" type="text" />

  <li ng-repeat="gigabytes in monthly | limitTo: limit()"> 
      {{ gigabytes | number:2}} 
  </li>
         
</div>

Upvotes: 1

PSL
PSL

Reputation: 123739

If you are using angular versions until 1.4 you would need to do:

 <li ng-repeat="gigabytes in monthly | limitTo:num || monthly.length">{{ gigabytes}}</li>

angular.module('app', []).controller('MyFilterDemoCtrl', MyFilterDemoCtrl);


function MyFilterDemoCtrl($scope) {
  $scope.monthly = [123.659855, 89.645222, 97.235644, 129.555555];
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>


<body ng-app="app" ng-controller="MyFilterDemoCtrl" ng-init="vm={}">
  Num:
  <input ng-model="vm.num" type="text" />
  <ul>
    <li ng-repeat="gigabytes in monthly | limitTo:vm.num || monthly.length track by $index">{{ gigabytes}}</li>
  </ul>

  <body>

With 1.4+ it is handled internally with a check on NaN

Limit To source snippet from 1.4:-

if (Math.abs(Number(limit)) === Infinity) {
  limit = Number(limit);
} else {
  limit = toInt(limit);
}
if (isNaN(limit)) return input;

So you could just do what you are doing currently:

<li ng-repeat="gigabytes in monthly | limitTo:num"> {{ gigabytes}} </li>

angular.module('app', []).controller('MyFilterDemoCtrl', MyFilterDemoCtrl);


function MyFilterDemoCtrl($scope) {
  $scope.monthly = [123.659855, 89.645222, 97.235644, 129.555555];
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>


<body ng-app="app" ng-controller="MyFilterDemoCtrl" ng-init="vm={}">
  Num:
  <input ng-model="vm.num" type="text" />
  <ul>
    <li ng-repeat="gigabytes in monthly | limitTo:vm.num  track by $index">{{ gigabytes}}</li>
  </ul>

  <body>

If you are using track by expression it should come in the end of the expression,

Note: track by must always be the last expression:

i.e.

for 1.4

<li ng-repeat="gigabytes in monthly | limitTo:num track by $index">

or for older versions

<li ng-repeat="gigabytes in monthly | limitTo:num || monthly.length track by $index">

Upvotes: 1

dfsq
dfsq

Reputation: 193291

The first thing you asked makes little sense, because when page loads num filter is going to be empty and hence no filter will apply to the list and all list items will be rendered by default. So you don't have to do anything special here.

As for showing message in case of number exceeding list items count, you can do it using ngShow directive ng-show="num > monthly.length". Something like this:

Num:
<input ng-model="num" type="text" />
<div ng-show="num > monthly.length">You only have {{monthly.length}} items.</div>
<li ng-repeat="gigabytes in monthly | limitTo:num"> {{ gigabytes}} </li>

Upvotes: 1

Related Questions