JavaScript
bootstrap
AngularJS

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

More than 3 years have passed since last update.


はじめに

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

登録してありますので、参考にしてください。