JFischer00
JFischer00

Reputation: 91

ng-repeat elements' indexes changing on sort

I have an HTML table with rows created using an ng-repeat and data using properties of objects in an object array. They are being sorted by a name column alphabetically. I have setup some simple editing using ng-show, ng-focus, and ng-blur, so that there is no need for a save button or something similar.

However, as I am editing the name column, if I type a first letter that would cause that row to be lower in the table, it sorts the table as I am still typing. I tried creating a "temp" object array, copying the original array into it, modifying the "temp" array when editing, then copying the temp array into the original array when editing is done. That didn't work; the same thing happened anyway.

After a little research, I learned that both the temp array and the original array were probably pointing to the same data, so I tried multiple ways of cloning the array. I finally got it to work...with one exception: when I edited the object to be sorted lower, it moved. When I tried to edit it again, it did all sorts of random, unexpected stuff.

After some diagnostics, I discovered that the indexes of the objects in the table (gotten from $index) were being changed when sorted. For example:

Table
-------------------------------------
|Name    |Age     |Phone   |Index   |
-------------------------------------
|George  |25      |928-7495|0       |
|John    |34      |342-0673|1       |
|Megan   |28      |834-1943|2       |
|Susan   |19      |274-8104|3       |
-------------------------------------

If I changed George to Tim, the index of that object becomes 3 also. All the other indexes stay the same. Can anyone tell me why this is happening and/or give me suggestions on how to fix this?

Upvotes: 0

Views: 1079

Answers (2)

JFischer00
JFischer00

Reputation: 91

So apparently I just didn't realize that the indexes changed every time I changed the data or the sorting of the data. After adding the index as a property of my objects, everything worked as expected.

Upvotes: 1

SoEzPz
SoEzPz

Reputation: 15922

This is how I use the orderBy Angularjs filter with column sorts that reverse on click. The "a" tag in the "th" is what controls the behavior. I have this in a directive, which is recommended, but the code can be in a controller.

I use the Angularjs orderBy filter as they state.

$filter('orderBy')(array, expression, reverse)
// This is the order of properties in the code below that looks like this
// $scope.rows = angularSortBy( $scope.rows, columnName, toggleOrderDirection( columnName ));

Each column has a font-awesome multi-arrow toggle called

<i class="fa fa-sort"></i>

Where columns would be something like this...

$scope.columns = { columnOne: { label: 'Column One', orderDirection: true, selected: false },
    columnTwo: { label: 'Column Two', orderDirection: true, selected: false },
    columnThree: { label: 'Column Three', orderDirection: true, selected: true }};

and rows could be anything you wish...

<table>
  <tr>
    <th>Sort By</th>
    <th ng-repeat="(key, value) in columns">
      <a href="" ng-click="orderBy( key )">{{ value.label }}</a>
      <span ng-if="value.selected">
      (<i class="fa fa-sort"></i>) // font-awesome arrow font.
    </th>
  </tr>

  <tr ng-repeat="row in rows">// stuff here</tr>


var angularSortBy = $filter( 'orderBy' ); // use Angular's built in filter to sort table.

$scope.orderBy = function( columnName ){
  resetAllSelectedStates(); // sets column.selected prop to false.
  setAsSelected( columnName, true );
  $scope.rows = angularSortBy( $scope.rows, columnName, toggleOrderDirection( columnName ));
}

function resetAllSelectedStates(){
  Object.keys( $scope.columns ).forEach( resetColumnPropertyToDefault );
}

function resetColumnPropertyToDefault( name ){
  $scope.columns[ name ].selected = false;
}

function setAsSelected( name ){
  $scope.columns[ name ].selected = true;
}

function toggleOrderDirection( name ){
    return $scope.columns[ name ].orderDirection = !$scope.columns[ name ].orderDirection;
}

Upvotes: 0

Related Questions