LoginSignup
49
53

More than 5 years have passed since last update.

AngularJSに挑戦!入門 ToDoをつくろう

Last updated at Posted at 2014-11-03

はじめに

AngularJSを使ったアプリケーションの作成に際して、
ToDoがもっとも簡単かつ覚えるのに適しているように思います。
(他のサイトでもよく見かけますし)
ですので、ToDoアプリを作ります。

要件

ToDoアプリを作るにあたって、何を作ればいいか最初に考えます。
1. Todoの追加
2. ToDo一覧の表示
3. 各ToDoに完了チェックボタンを付ける
4. 各ToDoを変更する
5. 各ToDoを削除する
6. 未完了数/完了数の表示

以下は、あったらいいな機能
1. フィルター
2. すべて完了にする
3. 追加・更新日時を表示

ほかにもありますが、今回はこの辺までとします。

機能実装

メイン

Todo.js
var TodoApp = angular.module('TodoApp', []);

TodoApp.controller('TodoCtrl', ['$scope', function ($scope) {
    $scope.todos = [];
    index = 0;

    $scope.add = function() {
        $scope.todos.push({id: index, message: $scope.message, done: false});
        $scope.message = "";
        index++;
    };

}]);
  1. 配列$scope.todosを初期化します。
  2. indexは、一意な数字を設定します。
  3. $scope.todos.push()で、配列に追加します。
Todo.html
<html>
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="Todo.css">
    <script type="text/javascript" src="Todo.js"></script>
    <title>Todo</title>
</head>
<body ng-app="TodoApp">
    <div class="container">
        <div class="jumbotron">
            <h2>Todo</h2>
        </div>
        <div ng-controller="TodoCtrl">
            <div class="bg-info">
                <label>ToDo: <label><input type="text" ng-model="message"><button ng-click="add()">追加</button>
            </div>
            <table class="table table-striped">
                <tr>
                    <th></th>
                    <th>ToDo:></th>
                </tr>
                <tr ng-repeat="todo in todos">
                    <td><input type="checkbox" ng-model="todo.done"></td>
                    <td><span class="done-{{todo.done}}">{{todo.message}}</span></td>
                </tr>
            </table>
        </div>
    </div>
</body>
</html>
Todo.css
.done-true {
    text-decoration: line-through;
    color: grey;
}
  1. <button ng-click="add()">は、クリックしたときに、add()関数を呼び出します。
  2. <input type="checkbox" ng-model="todo.done">完了・未完了のチェックボックスを表示しています。
  3. <span class="done-{{todo.done}}">{{todo.message}}</span>でメッセージの表示・非表示をしています。class="done-{{todo.done}}"で、CSSの設定を変更しています。

これで、追加はできました。

変更・削除を作る

変更・削除機能を追加します。
$scope.addの下に追加します。

Todo.js
    $scope.update = function(todo) {
        var message = window.prompt("変更",todo.message);
        if (message) {
            $scope.todos.forEach(function(td) {
                if (td.id == todo.id) {
                    td.message = message;
                }
            });
        }
    }

    $scope.delete = function(todo) {
        var index = 1;
        var t;
        for (var i = 0; $scope.todos.length; i++) {
            t = $scope.todos[i];
            if (t.id == todo.id) {
                index = i;
                break;
            }
        }
        $scope.todos.splice(index, 1);
    }
  1. 更新は、forEachで配列を回して、一致するidを探し、messageを更新します。
  2. 削除は、forで配列を回して、一致するidを探し、splice()で配列から削除します。
Todo.html
<html>
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="Todo.css">
    <script type="text/javascript" src="Todo.js"></script>
    <title>Todo</title>
</head>
<body ng-app="TodoApp">
    <div class="container">
        <div class="jumbotron">
            <h2>Todo</h2>
        </div>
        <div ng-controller="TodoCtrl">
            <div class="bg-info">
                <label>ToDo: <label><input type="text" ng-model="message"><button ng-click="add()">追加</button>
            </div>
            <table class="table table-striped">
                <tr>
                    <th></th>
                    <th>ToDo</th>
                    <th>削除</th>
                </tr>
                <tr ng-repeat="todo in todos">
                    <td><input type="checkbox" ng-model="todo.done"></td>
                    <td><span class="done-{{todo.done}}" ng-click="update(todo);">{{todo.message}}</span></td>
                    <td><button ng-click="delete(todo);">削除</button></td>
                </tr>
            </table>
        </div>
    </div>
</body>
</html>
  1. 先ほどのソースから、tableタグ内を修正します。
  2. テキストをクリックしたら、変更できるようにng-click="update(todo);イベントを追加します。
  3. <button ng-click="delete(todo);">削除ボタンを追加します。

未完了数/完了数の表示

先ほどのソースの$scope.deleteの後ろに以下のコードを追加します。

Todo.js
    $scope.remaining = function() {
        var count = 0;
        $scope.todos.forEach(function(todo) {
            count += todo.done;
        });
        return count;
    }

単に配列をforEachで回して、完了していたらcountを1つ上げています。

Todo.html
            <table class="table table-striped">
                <tr>
                    <th>{{remaining()}}/{{todos.length}}</th>
                    <th>ToDo</th>
                    <th>削除</th>
                </tr>

先ほどのソースのthタグを変更します。

使ってみよう

以下のようになりましたか?

todo01.jpg

  1. ToDo: 欄から入力して、一覧に追加されます。
  2. 一覧でチェックを付けると、取り消し線が引かれます。
  3. 一覧のメッセージをクリックすると、入力ダイアログが表示されて変更できます。
  4. 削除ボタンを押せば、削除できます。

機能拡張

あったらいいな機能を追加してみましょう。

フィルター

Todo.html
            <table class="table table-striped">
                <tr>
                    <th>{{remaining()}}/{{todos.length}}</th>
                    <th>ToDo: フィルター<input type="text" ng-model="q"></th>
                    <th>削除</th>
                </tr>
                <tr ng-repeat="todo in todos | filter:q">
                    <td><input type="checkbox" ng-model="todo.done"></td>
                    <td><span class="done-{{todo.done}}" ng-click="update(todo);">{{todo.message}}</span></td>
                    <td><button ng-click="delete(todo);">削除</button></td>
                </tr>
            </table>
  1. thタグにフィルター<input type="text" ng-model="q">を追加します。qにフィルター文字列が入ります。
  2. <tr ng-repeat="todo in todos">| filter:qを追加します。AngularJSのフィルター機能です。

すべて完了にする

$scope.remainingの後ろに追加します。

Todo.js
    $scope.complate = function() {
        $scope.todos.forEach(function(todo) {
            todo.done = true;
        });
    }
Todo.html
<th>{{remaining()}}/{{todos.length}}<button ng-click="complate();">すべて完了</button></th>

ヘッダー部分にボタンを追加します。

追加・更新日時を表示

$scope.add$scope.updateを変更して、$scope.complateの後ろに
$scope.getDateを追加します。

Todo.js
    $scope.add = function() {
        $scope.todos.push({id: index, message: $scope.message, date: $scope.getDate(), done: false});
        $scope.message = "";
        index++;
    };

    $scope.update = function(todo) {
        var message = window.prompt("変更",todo.message);
        if (message) {
            $scope.todos.forEach(function(td) {
                if (td.id == todo.id) {
                    td.message = message;
                    td.date = $scope.getDate();
                }
            });
        }
    }

    :
    :

    $scope.getDate = function() {
        var date = new Date();

        return date.getFullYear() + "/" +
               date.getMonth() + "/" +
               date.getDate() + " " +
               date.getHours() + ":" +
               date.getMinutes() + ":" +
               date.getSeconds()
    }

tableタグ内を変更します。

Todo.html
            <table class="table table-striped">
                <tr>
                    <th>{{remaining()}}/{{todos.length}}<button ng-click="complate();">すべて完了</button></th>
                    <th>ToDo: フィルター<input type="text" ng-model="q"></th>
                    <th>更新日時</th>
                    <th>削除</th>
                </tr>
                <tr ng-repeat="todo in todos | filter:q">
                    <td><input type="checkbox" ng-model="todo.done"></td>
                    <td><span class="done-{{todo.done}}" ng-click="update(todo);">{{todo.message}}</span></td>
                    <td><span>{{todo.date}}</td>
                    <td><button ng-click="delete(todo);">削除</button></td>
                </tr>
            </table>

使ってみよう

以下のようになりましたか?

todo02.jpg

  1. フィルター機能で、絞込みができるようになった
  2. すべて完了ですべてのToDoが完了状態になる
  3. 更新日時が表示される

おわりに

以上でAngularJSのToDoが作成できました。

今回作成したソースコードは、https://github.com/village333/angularJS_ToDo
登録してありますので、参考にしてください。

49
53
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
53