0

As you know after orderBy table loses its ordering and the $index value is from the sorted array, not from the original array. So if you pass an items array ['orange', 'banana','potato','apple'] to your ng-repeat, after an orderBy on the UI you will see them like this:

- apple   $index = 0
- banana  $index = 1
- orange  $index = 2
- potato  $index = 3

And if you now want to multi select items between apple($index = 0) and orange($index = 2) you might think that this will work:

for(index = 0; index <= 2; index++)
  console.log(items[index])

which is wrong, it will print : [orange, banana, potato]; not [apple, banana, orange].

I am looking a way to get the interval indexes of the displayed array after an orderBy, any ideas?

EDIT: To clarify, assume that on UI you have sorted items and then you select apple and then select orange:

✓ apple
  banana
✓ orange
  potato

I want a way to know the items in between those two selected, so that I can select all in between, in our case banana.

anvarik
  • 6,417
  • 5
  • 39
  • 53
  • you can simply use item instead of $index and get the original index by using $scope.items.indexOf(item). for a working example you can go to the following link. http://jsfiddle.net/0uksemjs/ – chandings Jan 27 '15 at 11:02
  • When you use a filter in the View, it is meant to format/modify the data for presentation purposes. Can you elaborate on *why* you need to the indices of the filtered/ordered array? And if it's more than for presentation purposes, then you should created an ordered copy of the array in the controller using `$filter("orderBy")` – New Dev Jan 27 '15 at 11:05
  • @NewDev I need the indices because I want to multi select the items on the view, so if I select apple, and then shift select orange, I want orange to be selected automatically regardless `orderBy` – anvarik Jan 27 '15 at 11:55
  • @anvarik, did any of the answers below address your question? – New Dev Feb 03 '15 at 19:39

3 Answers3

2

I think the easiest way to approach this is to pre-filter the array in the controller and operate on that array.

$scope.orderedItems = $filter("orderBy")($scope.Items, "+");

$scope.multiSelect = function(minIdx, maxIdx){
  //...
  $scope.selectedItems = $scope.orderedItems.slice(minIdx, maxIdx);
}

Of course, in the View you would ng-repeat over orderedItems without a filter:

<div ng-repeat="item in orderedItems">
  {{item}}
</div>
New Dev
  • 48,427
  • 12
  • 87
  • 129
1

This can be achieve by custom filter https://stackoverflow.com/a/22978169/1632286

app.filter('index', function () {
    return function (array, index) {
        if (!index)
            index = 'index';
        for (var i = 0; i < array.length; ++i) {
            array[i][index] = i;
        }
        return array;
    };
});

HTML:

<tr ng-repeat="item in items | index | orderBy:'Store.storeName'">

and then in HTML you can use item.index instead of $index.

This method is suitable for the collections of objects.

Please, take into account that this custom filter should be the first one in the list of all filters applied (orderBy etc.) and it will add the additional property index (the name is customizable) into the each object of the collection.

Community
  • 1
  • 1
squiroid
  • 13,809
  • 6
  • 47
  • 67
  • adding a filter on `index` does not solve my problem since it is not different then `items.indexOf('apple')` which is `3` and `items.indexOf('orange')` which is 0. What i want is to get the UI indexes, 0 and 2 so that I can access to 1, banana. – anvarik Jan 27 '15 at 13:25
1

Angular allows you to specify an alias for the data after filters have been applied. You could pass that alias into whatever method selected the items out of it along with the item or the $index which is the item's index within the ordered items.

 <div ng-repeat="item in items | orderBy: '+' as orderedItems">
    <a ng-click="itemSelected(orderedItems, $index)">{{item}}</a>
 </div>
adam0101
  • 29,096
  • 21
  • 96
  • 174
  • This is the appropriate approach. It shows the strength of Angular where these common tasks are handed from the framework, and you don't have re-invent the wheel in order to create them. +1 – Itai Spector Jan 22 '19 at 22:33