I'm trying to setup hotkeys for an old project that still uses angular 1.x and one of the features I was trying to add would be to select the first row from a table that is created with an NG-REPEAT
. I've been able to add in other functionality such has moving the selected row up / down because I pass in the selected row on ng-click="setSelected(this)"
which then lets me save the row and move it with selectedRow.$$prevSibiling
or selectedRow.$$nextSibiling
.
What I'm having a hard time figuring out is how can I set the selectedRow
from the controller.
Here is a quick example:
http://plnkr.co/edit/6jPHlYwkgF5raRWt?open=lib%2Fscript.js
JS:
App.controller('ActivitiesCtrl', [function() {
var vm = this;
vm.selectedRow = "Not set";
vm.activities = [
{
"id": 1,
"code": "ABC",
"person": "Joe"
},
{
"id": 2,
"code": "DFF",
"person": "Sally"
},
{
"id": 3,
"code": "ABC",
"person": "Sue"
},
{
"id": 4,
"code": "124",
"person": "Sam"
},
];
vm.setSelected = function(row) {
vm.selectedRow.selected = false;
vm.selectedRow = row;
vm.selectedRow.selected = true;
}
vm.moveNext = function() {
vm.setSelected(vm.selectedRow.$$nextSibling)
}
vm.setFirst = function() {
vm.setSelected("How do I set it...");
// How to set it? vm.setSelected(?????)
}
}]);
HTML:
<div ng-controller="ActivitiesCtrl as vm">
<table>
<thead>
<th>Id</th>
<th>Code</th>
<th>Person</th>
</thead>
<tbody>
<tr ng-repeat="activity in vm.activities track by activity.id" ng-click="vm.setSelected(this)" ng-class="{info: selected}">
<td>{{activity.id}}</td>
<td>{{activity.code}}</td>
<td>{{activity.person}}</td>
</tr>
</tbody>
</table>
{{vm.selectedRow | json}}
<hr />
<button ng-click="vm.setFirst()">Set First</button>
<button ng-click="vm.moveNext()">Next</button>
</div>
You can do this by setting the actual object from the array as selectedRow rather than using this
and set the class by checking if selectedRow === activity
in the ng-class.
This approach doesn't require mutating the objects
<tr
ng-repeat="activity in vm.activities track by activity.id"
ng-click="vm.setSelected(activity)"
ng-class="{info: vm.selectedRow == activity}"
>
Then you can use Array#findIndex() to get the current selectedRow index in the array and if a next one exists use it or go back to the first.
For the setFirst()
you just use vm.activities[0]
vm.selectedRow = null;
vm.setSelected = function (row) {
vm.selectedRow = row;
};
vm.moveNext = function () {
const {selectedRow:curr, activities:act} = vm;
if (curr !== null) {
let idx = act.findIndex(e => e == curr) + 1;
let next = act[idx] || act[0];
vm.setSelected(next);
}
};
vm.setFirst = function () {
vm.setSelected(vm.activities[0]);
};