How to order an array dynamically with Angular JS?

Asked

Viewed 3,805 times

2

I have a list of tasks. The list starts with unfinished tasks (task.done == false) first followed by completed tasks. However, when I select a task and select it as completed (task.done=true), I would like the list to be dynamically ordered and this task to go to the end of the list. Below is the example of my view controller.

app.controller ('crtl', function ($scope) {

 $scope.tasks = [
     { "task":"task1", "done": false}, 
     { "task":"task2", "done": true}, 
     { "task":"task3", "done": false}
 ];

 $scope.tasks.sort(order);


 function order (x, y) {
    return (x.done === y.done)? 0 : x? 1 : -1;
 };

 $scope.setDone = function (task) {
  task.done = true;

  //Como ordernar a lista dinamicamente ao alterar o booleano?
  //Esta maneira não funciona
  $scope.tasks.sort(order);

 };

});

4 answers

3

If it is a array/lista, you can use the filter. Example:

$scope.tasks.filter(function(){
    return  //sua condição
})

Documentation

3


There is a shorthand for the $FilterProvider that you can use:

$scope.variavel = $filter('orderBy')([colecao], '[propriedade]');

Applying to your case:

$scope.tasks = $filter('orderBy')($scope.tasks, 'done');

Bonus - If you want to filter only the cases where done=true;

$scope.doneTasks = $filter('filter')($scope.tasks,{'done': true});

Functional example to follow:

function SampleController($scope, $filter) {
  $scope.tasks = [
    { "task":"task1", "done": false}, 
    { "task":"task2", "done": true}, 
    { "task":"task3", "done": false}
  ];

  $scope.orderedTasks = $filter('orderBy')($scope.tasks, 'done', true);

  $scope.doneTasks = $filter('filter')($scope.tasks,{'done': true});

}
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

  </head>
  <body>
    <div ng-controller="SampleController">

      Ordered tasks:
      <table>
        <tr>
          <td>Task</td>
          <td>Done</td>
        </tr>
        <tr ng-repeat='i in orderedTasks'>
          <td>{{i.task}}</td>
          <td>{{i.done}}</td>
        </tr>
      </table>
      <br/><br/>
      Done tasks:
      <table>
        <tr>
          <td>Task</td>
          <td>Done</td>
        </tr>
        <tr ng-repeat='i in doneTasks'>
          <td>{{i.task}}</td>
          <td>{{i.done}}</td>
        </tr>
      </table>

      
    </div>
  </body>
</html>

0

0

Use the Angular JS filter orderby :

In control, create an order filter:

$scope.sortTasks = function(elem)
{
   switch (elem.done) {
     case false: return 1; break;
     case true:  return 2; break;
   }
}

And in the view, use it in orderby:

 <tr ng-repeat='val in tasks | orderBy:sortTasks'>
          <td>{{val.task}}</td>
          <td>{{val.done}}</td>
 </tr>

If you want to sort inside the controller, you can do so. But you need to change the filter to | orderBy:order and when doing ng-repeat, use the object taskOrdered:

$scope.taskOrdered = [];

 for (var i in $scope.tasks) {
      $scope.tasks[i].order = $scope.sortTasks($scope.tasks[i]);
      $scope.taskOrdered.push($scope.tasks[i]);
 }

Click here for more information on the sort filter:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.