Knockout-js-todo-list-sortable-tw-2

在此課程,將要做搜尋、篩選還有排序的功能

TodoListApp

Step1 – Sort function

這步驟將要用戶可以重新排序待辦事項,這裡我使用一個套件knockout-sortable.js,可以很輕易地完成這個功能。

index.html:

在待辦事項控件裡,綁定sortable: {data: todos()} 就完成了,當然別忘了要引用套件

<div class="form-group"  >
    <ul id="todo-list" data-bind="sortable: {data: todos()}">
        <li data-bind="css: { completed: completed, editing: editing }">
            <div class="view">
                <input class="todoCheckbox" data-bind="checked: completed" type="checkbox" >
                <label data-bind="text: title, event: { dblclick: $root.editItem }, css: {textDecoration:completed()==true}" ></label>
                <button class="close pull-right" data-bind="click: $root.remove">&times;</button>
            </div>
            <input class="edit" data-bind="value: title, valueUpdate: 'afterkeydown', enterKey: $root.saveEditing, escapeKey: $root.cancelEditing, selectAndFocus: editing, event: { blur: $root.saveEditing }">
        </li>
    </ul>
</div>

plugin in index.html :

<script type="text/javascript" src="js/libs/knockout-sortable.js"></script>

Step2 – Search and Filter function

介面

![TodoListApp](/images/knockoutjs_2_1.png)

這步驟將要建立一個搜尋功能並有一個快速篩選出完成項目與未完成項目功能,在此功能也引用另一個套件router。
index.html:

引用套件:

<script type="text/javascript" src="js/libs/director.js"></script>

搜尋與篩選控件:

    <div class="row" data-bind="visible: completedCount() || remainingCount()" style="   margin-top: 8px;">
        <div class="col-xs-5" style="padding-left: 0px;">
            <div class="input-group">
                <span class="input-group-btn">
                <button class="btn btn-default" type="button"><span class="glyphicon glyphicon-search"></span></button>
                </span>
                <input type="search" class="form-control" placeholder="Search"  data-bind="textInput: query" autocomplete="off">
        </div>
    </div>

    <div class="col-xs-3 ">
        <ul class="nav nav-pills" id="filters">
            <li data-bind="css: { active: isActive('all') }">
                <a data-bind="css: { selected: showMode() == 'all' }" href="#/all">All</a>
            </li>
            <li  data-bind="css: { active: isActive('active') }">
                <a data-bind="css: { selected: showMode() == 'active' }" href="#/active">Active</a>
            </li>
            <li  data-bind="css: { active: isActive('completed') }">
                <a data-bind="css: { selected: showMode() == 'completed' }" href="#/completed">Completed</a>
            </li>
        </ul>
    </div>
    <div class="col-xs-2" style="   margin-top: 8px;">
        <span id="todo-count">
            <strong data-bind="text: remainingCount">0</strong>
            <span data-bind="text: getLabel(remainingCount)"></span> left
        </span>
    </div>

</div>

待辦事件控件:

在待辦事項控件裡,我利用css的屬性來完成搜尋與篩選功能,用$root.filteredTodos($data)來確認是否符合條件。

<div class="form-group"  >
    <ul id="todo-list" data-bind="sortable: {data: todos()}">
        <li data-bind="css: { completed: completed, editing: editing },visible: $root.filteredTodos($data)">
            <div class="view">
                <input class="todoCheckbox" data-bind="checked: completed" type="checkbox" >
                <label data-bind="text: title, event: { dblclick: $root.editItem }, css: {textDecoration:completed()==true}" ></label>
                <button class="close pull-right" data-bind="click: $root.remove">&times;</button>
            </div>
            <input class="edit" data-bind="value: title, valueUpdate: 'afterkeydown', enterKey: $root.saveEditing, escapeKey: $root.cancelEditing, selectAndFocus: editing, event: { blur: $root.saveEditing }">
        </li>
    </ul>
</div>

App.js:

在filteredTodos funciton中,有兩階段,第一階段執行篩選而第二階段執行搜尋功能。

this.filteredTodos = function(todo) {
    var result = true;
        switch(this.showMode()){
      case 'active':
        if(todo.completed() != false)
            result = false;
        break;
        case 'completed':
         if(todo.completed() != true)
             result = false
       break;
        }
    if(result){
        var filter = this.query().toLowerCase();
        if(!filter){
            return true;
        }
        else{
          return todo.title().toLowerCase().indexOf(filter) !== -1;
        }
    }else
    {
        return false;
    }
};

在搜尋與篩選功能裡,我不用功能方式來執行,我採用路徑(URL)方式來執行,在app.js裡加了以下的代碼,來取得篩選的條件,也是前面提到的Router套件。

Router({'/:filter': viewModel.showMode}).init();

當你完成,你可以看到 TodoApp. PS: 我在完整案例裡有加一些功能,讓您們可研究一下。
TodoListApp
The complete working demo can be found here .

##Building a Todo app with Knockout.js (1) - A simple todo list

##Building a Todo app with Knockout.js (2) - Filter、Search and Sortable function