1

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

4
  • It's already going to be like you want: when page loads filter is empty and all items will get rendered. You don't need anything like monthly.lenght(). Commented Jul 29, 2015 at 21:09
  • 1
    limitTo:num || monthly.length Commented Jul 29, 2015 at 21:15
  • @PSL please check the edit of op Commented Jul 29, 2015 at 21:30
  • @slevin If you are using track by $index it should come in the end of the expression. see my answer update. Commented Jul 29, 2015 at 21:31

3 Answers 3

1

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">
Sign up to request clarification or add additional context in comments.

3 Comments

Works fine, but, sorry, still not showing every item when page loads.
@slevin Check out my demo (provided demos with 2 diff versions). What version of angular you are using?
I am so sorry, I made a typo. I fixed it and now works fine. Thanks for your time
1

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>

2 Comments

I dont think it will in 1.2 atleast (which OP seems to be using with global controller declaration), it is handled in newer versions though with the check if (isNaN(limit)) return input;
@dfsq You were right about showing a message, as for the filtering, please check my edited op
1

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>

1 Comment

Thanks. This also works fine! Its a matter of choice, if you prefer the data manipulation on the controller or the viewer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.