(4)
(0)
(1)
(0)
Total: 5 CakePHP Tips:ドラッグ&ドロップでデータを並び替える
マスターのメンテナンス機能やCMS系の機能を開発する際に、データの並びをユーザーが自由に設定できるようにしたいという要件はよくあります。
CakePHPとprototype.jsを使えば、ドラッグ&ドロップでデータの並びを設定することが簡単に実装できます。
今回のサンプルはこちらで確認できます。
id, name(果物名), position(position) の3カラムのfuruitsテーブルのデータを並び替えています。
方針
CakePHPではAjaxヘルパにドラッグ&ドロップのメソッドが用意されていますが、普通にjavascriptを書いたほうが簡単に実装できますので、今回はあえて自前で実装していきます。
処理の概要としては、以下のような感じです。
1.レイアウト:headタグ内でprototype.js、scriptaculous.jsを読み込む
2.ビュー:並び替えの対象用のコンテナのdivを設定
3.ビュー:データをループし、コンテナ内に表示情報と配列型のHIDDENでidを設置
4.ビュー:javascriptでドラッグ&ドロップが可能なSotableクラスにコンテナを指定
5.コントローラー:POSTされたデータは 並び順=>id となっているので、ループしながらsaveFieldメソッドで並び順を保存
ソースコード:コントローラー (controllers/fruits_controller.php)
-
<?php
-
class FruitsController extends AppController
-
{
-
var $name = 'Fruits';
-
-
function index() {
-
$this->pageTitle = 'ドラッグ&ドロップで並び替えできます';
-
$M = $this->Fruit;
-
$data = $M->findAll(NULL, NULL, "{$M->name}.position, {$M->name}.id desc");
-
$this->set('data', $data);
-
}
-
-
function change_position() {
-
$M = $this->Fruit;
-
$position_id =& $this->params['form']['position_id'];
-
foreach($position_id as $position => $id){
-
$M->id = $id;
-
$M->saveField('position', $position);
-
}
-
$this->Session->setFlash('並び替えの設定を保存しました。','display_info');
-
}
-
$this->redirect("/{$this->viewPath}/index/");
-
}
-
-
}
-
?>
[point]
・データは$_POST['position_id']に配列(並び => id)で渡される
・saveFieldメソッドでpositionを更新する
ソースコード:ビュー (views/fruits/index.thtml)
-
<form action="<?php echo $html->url('/fruits/change_position/') ?>" method="post" name="myForm">
-
<div id="position_box">
-
<?php foreach($data as $i => $_data): ?>
-
<div style="cursor:move; margin-bottom:3px; border:solid 1px gray; background-color:white">
-
<input type="hidden" name="position_id[]" value="<?php echo $_data['Fruit']['id'] ?>">
-
</div>
-
<?php endforeach; ?>
-
<center style="margin:5px">
-
<input type="submit" value="並び替えを保存する">
-
</center>
-
</div>
-
</form>
-
<script type="text/javascript"><!--
-
document.observe('dom:loaded', function(){
-
Sortable.create('position_box', {tag: 'div'});
-
});
-
//--></script>
[point]
・position_boxというdivコンテナを作成
・各レコード内にposition_id[]というid値を含んだHIDDENを設置
・javascript Sortableクラスにposition_boxコンテナを指定
※prototype.jsとscriptaculous.js?load=effects,dragdropはレイアウトで事前に読み込んでおくか、ビューの先頭でscriptタグを使って読み込ませる
ソースコード:モデル (models/fruit.php)
-
<?php
-
class Fruit extends AppModel
-
{
-
var $name = 'Fruit';
-
var $useTable = 'fruits';
-
}
-
?>
テーブルSQL
-
CREATE TABLE IF NOT EXISTS `fruits` (
-
`id` bigint(20) NOT NULL AUTO_INCREMENT,
-
`name` varchar(100) NOT NULL DEFAULT '',
-
`position` bigint(20) NOT NULL DEFAULT 99999,
-
PRIMARY KEY (`id`)
-
) ENGINE=MyISAM;
-
INSERT INTO `fruits` (`id`, `name`, `position`) VALUES
-
(1, 'オレンジ', 99999),
-
(2, 'リンゴ', 99999),
-
(3, 'バナナ', 99999),
-
(4, 'パイナップル', 99999),
-
(5, 'マンゴー', 99999),
-
(6, 'ぶどう', 99999),
-
(7, 'グレープフルーツ', 99999),
-
(8, 'レモン', 99999);
関連するその他の記事
Comments
Leave a Reply