こんばんは。ゆんぼうです。
今回は、Backbone.jsを使用して、チェックボックスを表示するテーブルを作成します。
今回使用する環境は下記の通りです。
Webブラウザ
・Mozilla Firefox (v34.05) https://www.mozilla.org/ja/firefox/new/
・FireBug (v2.0.7) https://addons.mozilla.org/ja/firefox/addon/firebug/
JavaScriptライブラリ
・Backbone.js (v1.1.2) http://backbonejs.org/
・Underscore.js (v1.7.0) http://underscorejs.org/
・jQuery (v2.1.1) http://jquery.com/
■チェックボックスのテーブル
【デモはこちら】
【ソースファイルはこちら】
チェックボックス付きのテーブルと登録・削除ボタンを作成します。
名前のテキストボックスに入力して、登録ボタンを押下すると、
テーブルにチェックボックスと名前が追加されます。
チェックボックスを選択して、削除ボタンを押下すると、そのテーブルデータが削除されます。
また、全てを選択するチェックボックスを押下すると、各チェックボックスが併せて変更されます。
index.html のhead に下記の内容を記述します。
<script type="text/template" id="template-user-table">
<input id="id_button_delete" type="button" value="<%= label.deleteButton %>">
<hr>
<table class="cls_table">
<thead>
<tr>
<th><input class="cls_all_checkbox" type="checkbox"></th>
<th><%= header.name %></th>
</tr>
</thead>
<tbody id="id_tbody">
</tbody>
</table>
</script>
<script type="text/template" id="template-user-table-item">
<th>
<input class="cls_checkbox" type="checkbox">
</th>
<td><%= data.name %></td>
</script>
テーブル全体のテンプレート template-user-table を作成します。
全て選択用のチェックボックスのスタイルクラス名は cls_all_checkbox と定義します。
テーブルデータ1件分のテンプレート template-user-table-item を作成します。
チェックボックスのスタイルクラス名は cls_checkbox と定義します。
main.js に下記の内容を記述します。
var UserCollection = Backbone.Collection.extend({
model : UserModel,
removeSelectedModel : function() {
var selectedCollection = this.models.filter(function(model) { // (17)
return model.isSelected;
});
this.remove(selectedCollection); // (18)
},
isSelectedAll : false,
selectModelAll : function(isSelected) {
this.isSelectedAll = isSelected;
_.each(this.models, function(model) { // (10)
model.isSelected = isSelected;
});
this.trigger('selectAll'); // (11)
},
selectModel : function() {
this.isSelectedAll = this.models.every(function(model) { // (3)
return model.isSelected
});
this.trigger('select'); // (4)
}
});
var UserTableView = Backbone.View.extend({
name : 'UserTableView',
events : {
'click .cls_all_checkbox' : 'onClickAllCheckbox', // (8)
'click #id_button_delete' : 'onClickDeleteButton' // (15)
},
initialize : function(args) {
this.collection = args.collection;
this.listenTo(this.collection, 'add', this.onAdd);
this.listenTo(this.collection, 'remove', this.onRemove); // (19)
this.listenTo(this.collection, 'select', this.onSelect); // (5)
this.listenTo(this.collection, 'selectAll', this.onSelectAll); // (12)
this.compiledTemplate = _.template($('#template-user-table').text());
this.currentHeader = null;
},
render : function() {
var tempData = {
'header' : {
'name' : '名前'
},
'label' : {
'deleteButton' : '削除'
}
};
this.$el.append(this.compiledTemplate(tempData));
return this;
},
renderItem : function() {
this.$el.find('#id_tbody').html('');
_.each(this.collection.models, function(model) {
this.$el.find('#id_tbody').append((new UserTableItemView({
'model' : model,
'collection' : this.collection
})).render().el);
}, this);
},
renderSelectAll : function() {
this.$el.find('.cls_all_checkbox').prop('checked', this.collection.isSelectedAll) // (7)
},
onAdd : function() {
console.log(this.name + '#onAdd');
this.renderItem();
},
onRemove : function() {
console.log(this.name + '#onRemove');
this.renderItem(); // (20)
},
onSelect : function() {
console.log(this.name + '#onSelect');
this.renderSelectAll(); // (6)
},
onSelectAll : function() {
console.log(this.name + '#onSelectAll');
this.renderItem(); // (13)
},
onClickAllCheckbox : function(event) {
console.log(this.name + '#onClickAllCheckbox');
this.collection.selectModelAll(event.target.checked); // (9)
},
onClickDeleteButton : function(event) {
console.log(this.name + '#onClickDeleteButton');
this.collection.removeSelectedModel(); // (16)
}
});
var UserTableItemView = Backbone.View.extend({
name : 'UserTableItemView',
tagName : 'tr',
events : {
'click .cls_checkbox' : 'onClickCheckbox' // (1)
},
initialize : function(args) {
this.model = args.model;
this.collection = args.collection;
this.compiledTemplate = _.template($('#template-user-table-item').text());
},
render : function() {
var templateData = {
'data' : this.model.toJSON()
};
this.$el.append(this.compiledTemplate(templateData));
if (this.model.isSelected) {
this.$el.find('.cls_checkbox').prop('checked', true) // (14)
}
return this;
},
onClickCheckbox : function(event) {
console.log(this.name + '#onClickCheckbox:' + event.target.checked);
this.model.isSelected = event.target.checked; // (2)
this.collection.selectModel();
}
});
各チェックボックスを押下したとき
(1) 各テーブルデータのチェックボックスのクリックイベントを監視します。
(2) チェックボックスを押下したとき、モデルの選択フラグ isSelected にチェック状態を設定します。また、コレクションの selectModel 関数を呼びます。
(3) コレクションの every 関数を使用して、全てのモデルの isSelected が true かどうかを真偽値を isSelectedAll に設定します。
(4) select イベントを発火します。
(5) select イベントを監視します。
(6) 全て選択用のチェックボックスを描画します。
(7) 全て選択用のチェックボックスのチェック状態は、コレクションの isSelectedAll プロパティの値で設定します。
全て選択用のチェックボックスを押下したとき
(8) 全て選択用のチェックボックスのクリックイベントを監視します。
(9) 全て選択用のチェックボックスを押下したとき、チェック状態を引数にして、コレクションの selectModelAll 関数を呼び出します。
(10) 全てのモデルの isSelected を同じ値に設定します。
(11) selectAll イベントを発火します。
(12) selectAll イベントを監視します。
(13) 各テーブルデータを描画します。
(14) モデルの isSelected が true のとき、チェックボックスのチェックを設定します。
削除ボタンを押下したとき
(15) 削除ボタンのクリックイベントを監視します。
(16) 削除ボタンを押下したとき、コレクションの removeSelectedModel 関数を呼びます。
(17) filter 関数を使用して、isSelected が true のモデル配列を取得します。
(18) コレクションの remove 関数を呼び出して、モデルを削除します。モデル配列が複数あるときは、複数のモデルを削除します。
(19) remove イベントを監視します。
(20) 各テーブルデータを描画します。
■チェックボックスのテーブル (ソート・複数のヘッダー)
【デモはこちら】
【ソースファイルはこちら】
先ほどのチェックボックスのテーブルに、複数のヘッダーとソート機能を追加します。
これらの追加に対する処理はありません。そのまま追加します。
リンク先のソースファイルをご覧ください。
以上です。
□過去の記事
Backbone.js入門その11「ソートテーブルを作る」
Backbone.js入門その10「テーブルと登録ボタンを作る」
Backbone.js入門その9「リストと詳細ボタンを作る」
Backbone.js入門その8「リストと削除ボタンを作る」
Backbone.js入門その7「リストと登録ボタンを作る」
Backbone.js入門その6「ModelとCollection」
Backbone.js入門その5「静的HTMLでBackbone.Viewを作る」
Backbone.js入門その4「SuperViewとSubViewのアクセスを作成する」
Backbone.js入門その3「Backbone.ViewでSubViewを作る」
Backbone.js入門その2「Backbone.Viewで複数の要素を作る」
Backbone.js入門その1「Backbone.Viewで1つの要素を作る」