Reputation: 91
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
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
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