anvarik
anvarik

Reputation: 6487

Angular get in-between indexes after orderBy

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.

Upvotes: 0

Views: 1377

Answers (3)

adam0101
adam0101

Reputation: 31005

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>

Upvotes: 1

New Dev
New Dev

Reputation: 49590

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>

Upvotes: 2

squiroid
squiroid

Reputation: 14027

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.

Upvotes: 1

Related Questions