Search code examples
angularjstemplatesangularfireangular-filters

How do I filter table data using Angular and Angularfire when a button is clicked using multiple views?


OK. I have searched for days for a suitable answer to my question, but I cannot find a relevant answer. It's possible that I have overlooked many things, but I am basically new to coding (+1 month).

I am working on an Angular + Firebase/Angularfire project that requires a todo app. It sounds fairly simple, but I am adding some extra features to it. One of the features that I have been having trouble with is filtering todos that are unfinished and those that are finished from one template to another.

What I would like to do is move all the todos that are marked "done", when clicked, to another table in another template view. So far, I've written 3 HTML templates: home (where the todos are entered), completed, and expired (I am still working on this one, which is another issue!). All of the templates are working when changing views using ui-view and a navigation button.

At the moment of the templates contain the same HTML table, so, of course, I am getting the same data in the tables when the data is placed in the "home" template. This is a non-issue; I knew that this would happen.

(Tried to post images, but I don't have 10 reputation points!) Here's the Plnkr: My Todo App

The question is: How can the data be filtered so that only those marked done appear in the "complete" template when checked on the "home" template? I know I have to write a filter, but I am not sure of the best way to go about it.

(I recently switched from a button to a checkbox just to make things a little easier for myself to see how things are working.)

<div class='row'> 
    <div class='col-md-10'>
    <table class='table table-hover'>
        <thead>
            <tr>
                <th>#</th>
                <th>Todo</th>
                <th>Date Due</th>
                <th>Done</th>
                <th></th> 
            </tr>
        </thead>
        <tbody>
            <tr class='results' ng-repeat='todo in todos'>
                <td><span>{{$index + 1}}</scan></td>
                <td><span>{{todo.text}}</span></td>
                <td><span>{{todo.date}}</span></td>
                <td><input type='checkbox' ng-model='todo.done'><span class='done-{{todo.done}}'></span></td>
                <td><button class='btn btn-danger' ng-click='removeTodo(todo)'>Delete</button></td>
            </tr>
        </tbody>
    </table>
</div>
</div>

This is the corresponding script:

app.controller('HomeCtrl', function($scope, $firebase) {
  var ref = new Firebase('https://xxxx.firebaseio.com/');
  var sync = $firebase(ref);

  $scope.todos = sync.$asArray();

  $scope.addTodo = function() {
    $scope.todos.$add({
      text: $scope.newTodo,
      date: $scope.newDate,
      done: false,
      expired: false
    });
    $scope.newTodo = '';
    $scope.newDate = '';
  };

  $scope.removeTodo = function(todo) {
    $scope.todos.$remove(todo);
  };
});

To add to this, I've tried writing a function that would do this, but looking at this so long has culminated in Javascript brain drain. I've done something like:

$scope.completedTodos = function(todo) {
   $scope.todos ... (Have no idea what to do?)
};

Yes, this obviously does not work! That's why I am considering just filtering the data. I could be wrong!


Solution

  • Here's something simple that might help get you up and running.

    First, add ng-change attribute for check-boxes for setting the Done value (in home.html and complete.html). This will save the done value to firebase.

    <input type='checkbox' ng-model='todo.done' ng-change="todos.$save(todo)">
    

    Secondly, for the complete.html template, add this filter to your ng-repeat.

    ng-repeat='todo in todos | filter:{done:true}'