CodeIgniterの学習 6 - Ajax (xajax)を使えるようにする 1 (実験)

さて、今日はCodeIgniterでxajaxを使えるようにする。
xajaxは名前の通りajaxのライブラリである。

特徴は説明するまでもないが、javascriptを意識することなく、
phpのファンクションとしてajaxを使った機能が作れてしまう優れものである。
javascriptでごりごり書くのが面倒な、ものぐさな俺にぴったり。


導入方法は、
Xajax perfect setup - http://codeigniter.com/wiki/Xajax_perfect_setup/
のとおりだが、一応やったことをメモしておく。


なお、実験レベルなので、「ファイルの配置が嫌だ」とか、「共通ロジック部分はモデルに入れるべきでしょう」
とかはとりあえず無視。
(あと不要なファイルの精査とかバグやセキュリティの調査もしてないので注意。
xajax Forums - http://community.xajaxproject.org/ で確認してね。)


作業メモ

ここはほとんど http://codeigniter.com/wiki/Xajax_perfect_setup/ に書いてあることと一緒。
訳してるだけじゃん、俺。


1)xajax project 本家 から最新ソースをダウンロードする。 - http://www.xajaxproject.org/download.php


2)解凍して xajax_core/以下のファイルを全部、 application/libraries/以下にコピーする。
(libraries/xajax*.phpがいっぱいできるのでディレクトリを掘りたい気もするが後回し)


3)application/libraries/xajax.inc.php を application/libraries/xajax.php にリネーム


4)application/init のディレクトリを作り、この中に init_ajax.php というファイルを作る。
init_ajax.php の中身は、http://codeigniter.com/wiki/Xajax_perfect_setup/ を見て instrationの4のソースをコピペする。
08/12/02追記: この4)の作業は不要。無くても動いた)


5)解凍したソース内の xajax_js ディレクトリを丸ごと ドキュメントルートにコピー(俺の場合は html/xajax_js)
この中にいろんなjavascriptがある。 不要なjsもあるがとりあえず後回し


6).htaccessmod_rewriteを修正し、 xajax_js ディレクトリ以下はリライトから除外する。

RewriteCond $1 !^(index\.php|images|img|css|js|xajax_js|robots\.txt)


7)サンプルコードを書く。(前々回のエントリのソースに追記する。詳細は下のソース内のコメント参照。)


php側ファンクション名がhoge3ならば 画面上では onclick=xajax_hoge3() みたいに呼び出せるのだが
直接呼ばれないように php側を _hoge3 画面側を xajax__hoge3() と「 _ 」を追加している。




ソース

コントローラー側:
application/controllers/tasklist.php
(前回のセッション実験ソースと混ざっている。)

_xajax_load() は同じのを何回も書くのが嫌だから、
とりあえず一カ所に寄せただけ。本当はモデルに書くべきか。

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// タスクリストというかいろいろ実験
class Tasklist extends Controller {
function Tasklist()
{
  parent :: Controller(); 
  // urlヘルパ
  $this -> load -> helper( 'url' ); 
  // xajaxを有効に
  $this -> load -> library( 'xajax' ); 
  // _hoge3をajax(xajax)のファンクション化する。
  //javascript側では xajax__hoge3 で呼び出せる
  $this -> xajax -> registerFunction( array( '_hoge3', &$this, '_hoge3' ) );
  $this -> xajax -> processRequest();
} 

function index()
{ 
  // xajaxの準備用、一カ所にまとめておく。これってモデルに移動できたっけ?
  foreach( $this -> _xajax_load() as $k => $v ) {
    $data[$k] = $v;
  } 
  // セッションの値確認テスト用
  $data["info"] = ( $this -> db_session -> userdata( 'info' ) ) ?
  $this -> db_session -> userdata( 'info' ) : "中に誰もいませんよ";

  $this -> load -> view( 'tasklist_view', $data );
} 

function hoge1()
{ 
  // xajaxの準備用、一カ所にまとめておく。これってモデルに移動できたっけ?
  foreach( $this -> _xajax_load() as $k => $v ) {
    $data[$k] = $v;
  } 
  // セッションに値を格納
  $this -> db_session -> set_userdata( 'info', 'なんか入ってきた:' 
  . date( "H:i:s", time() ) ); 

  // セッションから取り出し
  $data["info"] = $this -> db_session -> userdata( 'info' );
  $this -> load -> view( 'tasklist_view', $data );
} 

function hoge2()
{ 
  // xajaxの準備用、一カ所にまとめておく。これってモデルに移動できたっけ?
  foreach( $this -> _xajax_load() as $k => $v ) {
    $data[$k] = $v;
  } 
  // セッションの破棄
  $this -> db_session -> sess_destroy();
  redirect( '/tasklist' );
} 

function _hoge3( $number )
{ 
  // xajax用(ボタン押下時のイベント)
  $objResponse = new xajaxResponse(); 
  // SomeElementId とついたID内をinnerHTML書き換えで、入れ替える。
  $objResponse -> Assign( "SomeElementId", "innerHTML", "ここがajaxで書き変わった!足し算結果:" . ( $number + 3 ) );
  return $objResponse;
} 

function _xajax_load()
{ 
  // とりあえずまとめただけ
  $xajax_js = $this -> xajax -> getJavascript( base_url() ); 
  // _hoge3は、xajax_ をつけて xajax__hoge3(引数) で呼べる
  // 外部から直接呼ばれないようにファンクション名を
  //_hoge3としてアンダーバーをつけているので_が2つある
  $content = '<div id="SomeElementId">下のボタンを押してちょ、中身が書き変わるよ</div>';
  $content .= '<p/><input type="button" value="押してみる" onclick="xajax__hoge3(2);">';
  return array( "xajax_js" => $xajax_js, "content" => $content );
} 
} 
/**
* End of file tasklist.php
*/
/**
* Location: ./application/controllers/tasklist.php
*/
 ?>


ビュー側:
application/views/tasklist_view.php
コントローラ側で$contentを作っているので、 $contentを貼っているだけ。
コントローラ側で <input … onclick="xajax__hoge3(2);" > の部分を事前に作っておかなければならないのがミソだったような記憶が。
それ以外はビュー側に書いてもかまわない。

↑訂正、$content は全部ビューに直接書いても動いた。

あと、ヘッダ部分に

<?=$xajax_js?>

が必要。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tasklistへようこそ</title>
<?=$xajax_js?>
<style type="text/css">
body {
 background-color: #fff;
 margin: 40px;
 font-family: Lucida Grande, Verdana, Sans-serif;
 font-size: 14px;
 line-height:26px;
 color: #4F5155;
}
a {
 color: #003399;
 background-color: transparent;
 font-weight: normal;
 text-decoration:underline;
}
h1 {
 color: #444;
 background-color: transparent;
 border-bottom: 1px solid #D0D0D0;
 font-size: 16px;
 font-weight: bold;
 margin: 24px 0 2px 0;
 padding: 5px 0 6px 0;
}
h2 {
 color: #666;
 background-color: transparent;
 border: 0px ;
 font-size: 14px;
 font-weight: bold;
 margin-top:20px;
}
#msg_red{
 color:#dc143c;
 font-weight: bold;
 background: #ffbbcc;
 border:1px solid #ffaacc;
 padding:10px;
 font-size:1.4em;
}
#SomeElementId{
 color:#ff0000;
 font-weight: bold;
 background: #b8e08f;
 border:1px solid #bfdb58;
 padding:10px;
 font-size:1.4em;
}
</style>
</head>
<body>
<h1>Tasklistへようこそ!</h1>
<h2>↓セッションの値確認↓</h2>
<p id="msg_red"><?= $info ?></p>
<ul>
<li><a href="/tasklist/hoge1">/tasklist/hoge1 に行ってセッションを格納してみる</a></li>
<li><a href="/tasklist/hoge2">/tasklist/hoge2 でセッションを破棄して/tasklistにリダイレクト</a></li>
</ul>

<h2>↓XAJAXのテスト↓</h2>
<?=$content?>

</body>
</html>


動作結果

こんな感じ、ボタンを押すと足し算結果が画面に入る。
実際これを使いこなすと、かなり複雑な事がいろいろできる。
当然、innerHTML書き換えだけでなく、

$objResponse -> addScript("window.alert('hoge');");

みたいにjavascriptの呼び出しもできる。


ボタンを押す:

ポチッっとな:


次は何を試そうか。まだ学習らしい学習してないな。

ああそうだ、次はログイン認証か、キャプチャでもやろう。