Clear All Completed page

Clear completed todo’s (event bindings)

The problem

Make the "Clear completed" button work. When the button is clicked, It should destroy each completed todo.

What you need to know

  • The can-stache-bindings Presentation’s DOM Event Bindings

  • Use on:EVENT to listen to an event on an element and call a method in can-stache. For example, the following calls doSomething() when the <div> is clicked.

    <div on:click="doSomething()"> ... </div>
    

The solution

Click to see the solution

Update models/todo.js to the following:

// models/todo.js
import {DefineMap, DefineList, realtimeRestModel} from "can";

const Todo = DefineMap.extend("Todo", {
    id: {type: "string", identity: true},
    name: "string",
    complete: {
        type: "boolean",
        default: false
    },
    toggleComplete() {
        this.complete = !this.complete;
    }
});

Todo.List = DefineList.extend("TodoList", {
    "#": Todo,
    get active() {
        return this.filter({
            complete: false
        });
    },
    get complete() {
        return this.filter({
            complete: true
        });
    },
    get allComplete() {
        return this.length === this.complete.length;
    },
    get saving() {
        return this.filter(function(todo) {
            return todo.isSaving();
        });
    },
    updateCompleteTo(value) {
        this.forEach(function(todo) {
            todo.complete = value;
            todo.save();
        });
    },
    destroyComplete(){
        this.complete.forEach(function(todo){
            todo.destroy();
        });
    }
});

Todo.connection = realtimeRestModel({
    url: "/api/todos/{id}",
    Map: Todo,
    List: Todo.List
});

export default Todo;

Update index.stache to the following:

<!-- index.stache -->
<can-import from="~/components/todo-create/" />
<can-import from="~/components/todo-list/" />
<section id="todoapp">
    <header id="header">
        <h1>{{ this.appName }}</h1>
        <todo-create/>
    </header>
    <section id="main" class="">
        <input id="toggle-all" type="checkbox"
            checked:bind="this.allChecked"
            disabled:from="this.todosList.saving.length" />
        <label for="toggle-all">Mark all as complete</label>
        <todo-list todos:from="this.todosList" />
    </section>
    <footer id="footer" class="">
        <span id="todo-count">
            <strong>{{ this.todosList.active.length }}</strong> items left
        </span>
        <ul id="filters">
            <li>
                <a class="selected" href="#!">All</a>
            </li>
            <li>
                <a href="#!active">Active</a>
            </li>
            <li>
                <a href="#!completed">Completed</a>
            </li>
        </ul>
        <button id="clear-completed"
            on:click="this.todosList.destroyComplete()">
            Clear completed ({{ this.todosList.complete.length }})
        </button>
    </footer>
</section>