Smartyを利用しながらページ遷移をAjaxでシームレスに行ってみることにしました。
参考にしたのはAjax と Smarty: 第 1 回 Smarty を使って Ajax アプリケーションを開発するです。
若干ややこしかったので、自分なりに簡易にしてみました。
具体例として、ログイン画面→ログイン後のマイページ をAjaxで遷移するコードを書いてみました。
(ログイン失敗のメッセージもAjaxでページ遷移せずに表示します)
まず、ページのSmartyテンプレートです。
基本的にこのテンプレートをどのページでも使い続け、テンプレート内の demo_div 内をページによって書き換えていきます。(文字数制限のためハイライトOFFです)
●demo_page.tpl (Smarty ページテンプレート)
Demo
test
{include file="demo_form.tpl"}
demo_div 内には、最初に表示するテンプレートをインクルードします。
ログイン用の情報を入れるテキストボックスです。最初に、demo_page.tpl に表示されるテンプレートです。
ログインに失敗した場合、$auth_err に true がはいり、エラーメッセージを表示します。
●demo_mypage.tpl (Smartyテンプレート)
ログインが完了しました。
ページ遷移なしでコンテンツが切り替わりました。
更新ボタンを押下すると、ログイン画面に戻ってしまうので、セッション変数を上手く使うなど対策が必要。
ログインが成功すると demo_page.tpl に表示されるテンプレートです。
つぎに、PHPファイルです。
クライアントはこのPHPにアクセスし、どのページを表示するかのmodeに基づいて処理を割り振ります。(MVCのコントローラみたいな感じですね)
今回はすべてこのPHPファイルにアクセスしていますが、別にページ毎にPHPファイルを作ってもかまいません。(ただしクライアントに表示されるURLは最初にアクセスしたページのままです。)
header("Cache-Control: no-cache");
header("Pragma: no-cache");
require 'smarty/libs/Smarty.class.php';
$smarty->compile_check = true;
$smarty->debugging = false;
$smarty->force_compile = 1;
//Smartyのディレクトリ設定(キャッシュやテンプレート置き場など)
$smarty->template_dir = "smarty/templates";
$smarty->compile_dir = "smarty/templates_c";
$smarty->cache_dir ="smarty/cache";
//$mode変数にどの画面を表示するかの値を持たす。
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : "default";
//どの画面を表示するか判定。
switch ($mode){
case "login":
//ログイン処理を行う
auth($smarty);
return;
break;
default:
//デフォルトの場合、ページテンプレートを表示
$smarty->assign("mode", "login");
$smarty->assign("auth_err", false);
$smarty->display('demo_page2.tpl');
break;
}
function auth($smarty){
//認証処理
if ( $_POST["user"] != "hoge" || $_POST["pass"] != "hoge" ){
//認証失敗。ログインページテンプレートを表示。
$smarty->assign("mode", "login");
$smarty->assign("auth_err", true);
$smarty->display('demo_form2.tpl' );
return;
}
mypageDisp($smarty);
}
function mypageDisp($smarty){
//認証OK メインコンテツ表示
$smarty->assign("mode", "mypage");
$smarty->display('demo_mypage.tpl');
return;
}
?>
最後に、JavaScriptのファイルです。
●demo_js.js
function submitDemoForm() {
//form要素を選択
var form = $("form#demo_form");
//ajaxで別ページをロード
$.ajax({
type: "POST",
//formにaction属性あればその値にページ遷移、なければ今と同じページ表示
url: form.attr("action") ? form.attr("action") : document .URL,
data: $(form).serialize(),
dataType: "text",
beforeSend: function(xhr) {
//ヘッダに追加
xhr.setRequestHeader("Ajax-Request", "true");
},
success: function(response) {
//ajax通信が完了後、レスポンスしたデータを表示。
$("#demo_div").html(response);
}
});
return false;
}
Ajaxで POST データを submit する時ですが、jQueryの $("form").submit(function(){ }); のイベントは捕まえられないようです。