#はじめに
AngularJSを使ったアプリケーションの作成に際して、
ToDoがもっとも簡単かつ覚えるのに適しているように思います。
(他のサイトでもよく見かけますし)
ですので、ToDoアプリを作ります。
#要件
ToDoアプリを作るにあたって、何を作ればいいか最初に考えます。
- Todoの追加
- ToDo一覧の表示
- 各ToDoに完了チェックボタンを付ける
- 各ToDoを変更する
- 各ToDoを削除する
- 未完了数/完了数の表示
以下は、あったらいいな機能
- フィルター
- すべて完了にする
- 追加・更新日時を表示
ほかにもありますが、今回はこの辺までとします。
#機能実装
##メイン
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++;
};
}]);
- 配列
$scope.todos
を初期化します。 -
index
は、一意な数字を設定します。 -
$scope.todos.push()
で、配列に追加します。
<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>
.done-true {
text-decoration: line-through;
color: grey;
}
-
<button ng-click="add()">
は、クリックしたときに、add()
関数を呼び出します。 -
<input type="checkbox" ng-model="todo.done">
完了・未完了のチェックボックスを表示しています。 -
<span class="done-{{todo.done}}">{{todo.message}}</span>
でメッセージの表示・非表示をしています。class="done-{{todo.done}}"で、CSSの設定を変更しています。
これで、追加はできました。
##変更・削除を作る
変更・削除機能を追加します。
$scope.addの下に追加します。
$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);
}
- 更新は、
forEach
で配列を回して、一致するid
を探し、message
を更新します。 - 削除は、
for
で配列を回して、一致するid
を探し、splice()
で配列から削除します。
<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>
- 先ほどのソースから、tableタグ内を修正します。
- テキストをクリックしたら、変更できるように
ng-click="update(todo);
イベントを追加します。 -
<button ng-click="delete(todo);">
削除ボタンを追加します。
##未完了数/完了数の表示
先ほどのソースの$scope.delete
の後ろに以下のコードを追加します。
$scope.remaining = function() {
var count = 0;
$scope.todos.forEach(function(todo) {
count += todo.done;
});
return count;
}
単に配列をforEach
で回して、完了していたらcount
を1つ上げています。
<table class="table table-striped">
<tr>
<th>{{remaining()}}/{{todos.length}}</th>
<th>ToDo</th>
<th>削除</th>
</tr>
先ほどのソースのthタグを変更します。
##使ってみよう
以下のようになりましたか?
- ToDo: 欄から入力して、一覧に追加されます。
- 一覧でチェックを付けると、取り消し線が引かれます。
- 一覧のメッセージをクリックすると、入力ダイアログが表示されて変更できます。
- 削除ボタンを押せば、削除できます。
#機能拡張
あったらいいな機能を追加してみましょう。
##フィルター
<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>
- thタグに
フィルター<input type="text" ng-model="q">
を追加します。q
にフィルター文字列が入ります。 -
<tr ng-repeat="todo in todos">
に| filter:q
を追加します。AngularJSのフィルター機能です。
##すべて完了にする
$scope.remaining
の後ろに追加します。
$scope.complate = function() {
$scope.todos.forEach(function(todo) {
todo.done = true;
});
}
<th>{{remaining()}}/{{todos.length}}<button ng-click="complate();">すべて完了</button></th>
ヘッダー部分にボタンを追加します。
##追加・更新日時を表示
$scope.add
と$scope.update
を変更して、$scope.complate
の後ろに
$scope.getDate
を追加します。
$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タグ内を変更します。
<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>
##使ってみよう
以下のようになりましたか?
- フィルター機能で、絞込みができるようになった
- すべて完了ですべてのToDoが完了状態になる
- 更新日時が表示される
#おわりに
以上でAngularJSのToDoが作成できました。
今回作成したソースコードは、https://github.com/village333/angularJS_ToDoに
登録してありますので、参考にしてください。