第7回ではタスクの管理に必要な機能を実装しました。今回はタスクの追加を簡易的にAjax化してみます。
タスクの追加をAjax化する
CakePHPにはWebアプリケーションのAjax化を支援するAJAXヘルパーというヘルパーがあります。これを使うことでよくあるAjax処理をJavaScriptをまったく記述せずに実装することができます。
必要なJavaScriptライブラリの入手
AJAXヘルパーではJavaScriptライブラリのPrototypeとscript.
builder.js
controls.js
dragdrop.js
effects.js
prototype.js
scriptaculous.js
slider.js
unittest.js
Tasksコントローラの修正
Ajax化にあたって、
<?php
class TasksController extends AppController {
var $name = 'Tasks';
var $uses = array('Task');
var $helpers = array(
'Javascript',
'Ajax',
);
function index() {
$this->set('yet_tasks', $this->Task->findAllByStatus('yet', null,
'Task.created ASC'));
$this->set('done_tasks', $this->Task->findAllByStatus('done',
null, 'Task.modified DESC'));
}
function add() {
if (empty($this->data)) return;
$this->Task->save($this->data, true, array('content', 'created',
'modified'));
$this->set('yet_tasks', $this->Task->findAllByStatus('yet', null,
'Task.created ASC'));
$this->layout = 'ajax';
}
function done($id) {
if ($this->Task->findById($id)) {
$this->Task->id = $id;
$this->Task->save(array('status' => 'done'));
}
$this->redirect('/tasks');
}
function edit($id) {
$task = $this->Task->findById($id);
if (!$task) {
$this->redirect('/tasks');
return;
}
if (!empty($this->data)) {
$task['Task']['content'] = $this->data['Task']['content'];
$this->Task->save($task);
}
$this->set('task', $task);
}
function del($id) {
$this->Task->del($id);
$this->redirect('/tasks');
}
}
この変更のポイントは2つです。TasksControllerクラスに追加したメンバ変数の$helpersでは、JavaScriptヘルパーとAjaxヘルパーの使用を明示しています。今まで使用してきたHTMLヘルパーは明示しなくても自動的に定義されていましたが、
var $helpers = array(
'Javascript',
'Ajax',
);
addアクションの最後の行ではレイアウトをAjax用に変更しています。CakePHPで用意されたajaxレイアウトはアクションのビュー出力以外の要素を一切表示しないためAjax用の出力に適したレイアウトとなっています。
$this->layout = 'ajax';
indexビューの修正
indexビューの未完了タスクの表示までを、
<?php echo $javascript->link('prototype') ?>
<?php echo $ajax->form('/tasks/add', 'post', array('update' => 'yet_tasks')) ?>
<p><?php echo $html->input('Task/content') ?>
<?php echo $html->submit('タスクを追加') ?></p>
</form>
<h2>未完了タスク</h2>
<div id="yet_tasks">
<?php echo $this->renderElement('yet_tasks_table') ?>
</div>
<h2>完了タスク</h2>
<table>
<tr>
<th>Id</th>
<th>タスク内容</th>
<th>状態</th>
<th>操作</th>
<th>作成日</th>
</tr>
<?php foreach ($done_tasks as $task) { ?>
<tr>
<td><?php echo h($task['Task']['id']) ?></td>
<td><?php echo h($task['Task']['content']) ?></td>
<td><?php echo h($task['Task']['status']) ?></td>
<td><?php echo $html->link('削除', '/tasks/del/' . $task['Task']['id'], null, '削除してもよろしいですか?') ?></td>
<td><?php echo h($task['Task']['created']) ?></td>
</tr>
<?php } ?>
</table>
1行目ではprototypeライブラリを読み込んでいます。先ほどapp/
<?php echo $javascript->link('prototype') ?>
3行目ではform要素の開始タグの表示がAJAXヘルパーによって行われるようになりました。
<?php echo $ajax->form('/tasks/add', 'post', array('update' => 'yet_tasks')) ?>
AJAXヘルパーの第1引数はデータ送信先のパス、
<div id="yet_tasks">
<?php echo $this->renderElement('yet_tasks_table') ?>
</div>
タスクの追加では未完了タスクが変更されるため、
$this->renderElement()とは
ビュー内で実行する$this->renderElement()メソッドは、
yet_tasks_tableエレメントとaddビューの作成
yet_
<table>
<tr>
<th>Id</th>
<th>タスク内容</th>
<th>状態</th>
<th>操作</th>
<th>作成日</th>
</tr>
<?php foreach ($yet_tasks as $task) { ?>
<tr>
<td><?php echo h($task['Task']['id']) ?></td>
<td><?php echo h($task['Task']['content']) ?></td>
<td><?php echo h($task['Task']['status']) ?></td>
<td>
<?php echo $html->link('完了', '/tasks/done/' . $task['Task']['id'],
null, '完了してもよろしいですか?') ?>
<?php echo $html->link('編集', '/tasks/edit/' . $task['Task']['id']) ?>
<?php echo $html->link('削除', '/tasks/del/' . $task['Task']['id'],
null, '削除してもよろしいですか?') ?>
</td>
<td><?php echo h($task['Task']['created']) ?></td>
</tr>
<?php } ?>
</table>
addビューはapp/
<?php echo $this->renderElement('yet_tasks_table') ?>
以上でタスク追加のAjax化が完了しました。なお、
修正後のアプリケーションにアクセスし、
また、
AJAXヘルパーについては、
次回予定は、