タスクの編集フォーム
2015/07/16
前回はTodoListのタスクを新規作成する機能を作りました。
今回は、タスクのタイトル(件名)を修正するフォームを表示します。
JavaScript プログラムに手を付ける前に、先回りして CSS を書き換えておきます。
#todo-list {
label.completed span {
color: #888;
text-decoration: line-through;
}
button[disabled] {
color: #888;
}
button + button {
margin-left: 4px;
}
span.modifying {
font-weight: bold;
color: #800;
}
span.button {
cursor: pointer;
background-color: #888;
color: #fff;
margin-left: 4px;
padding: 4px 8px;
font-size: 60%;
}
}
button + button {
の行から下(最終行を除く)を挿入してください。
では、始めましょう。todo_list.es6
を開いてください。まず、TodoList
クラスの init()
メソッドを次のように書き換えます(4行目を追加)。
init() {
this.ds = new TaskStore();
this.ds.attach(this);
this.editingTask = null;
this.ds.refresh();
}
editingTask
という名前の属性に null
をセットしています。後で見るように、この属性は編集中のタスク(オブジェクト)を保持することになります。
次に、render()
メソッドを次のように変更します(下から2行目を挿入)。
render(m) {
m.ul(m => {
this.ds.tasks.forEach(task => {
m.li(m => this.renderTask(m, task));
});
});
this.renderCreateForm(m);
this.renderUpdateForm(m);
}
さらに、renderTask()
メソッドを修正(6行目、9-10行目を挿入)。
renderTask(m, task) {
m.class({ completed: task.done });
m.label(m => {
m.onclick(e => this.ds.toggleTask(task));
m.input({ type: 'checkbox', checked: task.done }).sp();
m.class({ modifying: task.modifying });
m.span(task.title);
});
m.onclick(e => this.editTask(task));
m.span('Edit', { class: 'button' });
}
既存の renderCreateForm()
メソッドの下に以下の2個のメソッドを追加します。
renderUpdateForm(m) {
m.formFor('task', m => {
m.onkeyup(e => this.refresh());
m.textField('title').sp();
m.attr({ disabled: this.val('task.title').trim() === '' });
m.btn('Update');
});
}
editTask(task) {
if (this.editingTask) this.editingTask.modifying = false;
task.modifying = true;
this.editingTask = task;
this.val('task.title', task.title);
this.refresh();
}
各タスクのタイトルの右に表示される「Edit」ボタン(<span>
要素)をクリックすると editTask()
メソッドが呼び出されるようにしました。
このメソッドは編集したいタスク(task
)の「修正中フラグ(modifying
)」を true
にし、それを TodoList
コンポーネントの editingTask
属性にセットします。そして、その title
属性の値を編集フォームの title
フィールドに入れて TodoList
コンポーネントを再描画します。
では、ブラウザで動作確認をしましょう。まず、初期画面はこうなります。
「猫のえさを買う。」の右の「Edit」ボタンをクリックすると、こう変化します。
ラベルが赤くなったのは、このタスクに「修正中フラグ(modifying
)」が付いたためです。renderTask()
メソッドの中に次のような記述があります。
m.class({ modifying: task.modifying });
m.span(task.title);
この結果、<span class="modifying">猫のえさを買う。</span>
のような HTML タグが生成され、本稿冒頭で書き換えた CSS の効果で色が赤くなるのです。
UI をもう少し改善しましょう。タスクの編集をキャンセルできるようにします。renderUpdateForm()
メソッドを次のように書き換えます(下から3行目を追加)。
renderUpdateForm(m) {
m.formFor('task', m => {
m.onkeyup(e => this.refresh());
m.textField('title').sp();
m.attr({ disabled: this.val('task.title').trim() === '' });
m.btn('Update');
m.btn('Cancel', { onclick: e => this.reset() });
});
}
そして、editTask()
メソッドの下に reset()
メソッドを追加します。
reset() {
if (this.editingTask) this.editingTask.modifying = false;
this.editingTask = null;
this.val('task.title', '');
this.refresh();
}
このメソッドは、編集中のタスクの「修正中フラグ(modifying
)」を false
にしたり、編集フォームの title
フィールドを空にしたりします。
ブラウザの表示は次のようになります。
適当な「Edit」ボタンをクリックして「Cancel」ボタンをクリックすると、初期画面に戻ります。
UI の改善を続けます。同じタスクの横の「Edit」ボタンを2回連続してクリックしたとき、そのタスクの編集がキャンセルされるようにしましょう。
editTask()
メソッドを次のように書き換えてください。
editTask(task) {
if (this.editingTask === task) {
this.reset();
}
else {
if (this.editingTask) this.editingTask.modifying = false;
task.modifying = true;
this.editingTask = task;
this.val('task.title', task.title);
this.refresh();
}
}
ブラウザで動作確認してください。「猫のえさを買う。」の右の「Edit」ボタンを2回連続してクリックして、画面が初期状態に戻れば OK です。
今回はここまで。
次回は、このフォームから Ajax リクエストでデータベースを更新する処理を実装します。