Seasar DI Container with AOP

Kumu.Ajaxとは

Kumu.AjaxはTeedaでAjaxを簡単に使用できるように作られたjavascriptのライブラリです。

Kumu.AjaxはTeedaに依存しているわけではありません。サーバーサイド側は自由に選択することができます。

またKumu.Ajaxはkumu.jsに依存していません。ajax.js単体で使用する事ができます。

Kumu.Ajaxは以下の機能を提供します。

  1. Ajaxによる非同期通信
  2. 通信状態ごとの関数実行
  3. Teedaとの連携機能
  4. JSONレンダリング
  5. Formの値の取得
  6. JSONの文字列化(この機能は将来kumu.jsに移行します)

Ajaxによる非同期通信

Kumu.Ajaxは主にKumu.Ajax.executeTeedaAjaxでTeedaと連携して使用するケースが多いですが、低レベルな非同期通信を行う事もできます。

Ajaxで通信する際にはS2AjaxComponentを取得して各種パラメータをセットします。

var ajax = Kumu.Ajax.getS2AjaxComponent();
ajax.url = '/hogehoge.do';
ajax.params = {'hoge':1, 'foo':2};
ajax.doAction = function(response) {
};
Kumu.Ajax.executeAjax(ajax);

AjaxComponentにセットする値は以下です。

  • url

    リクエスト先URLです。

    絶対パスで指定します。

  • params

    送信するリクエストパラメータです。

    URLEncodeは内部で自動で行います。

  • doAction

    コールバック関数を指定します。

    コールバック関数はレスポンスを渡され実行されます。

  • method

    actionのmethodを指定します。

    GET or POSTを文字列で指定します。デフォルトでは'GET'です。

  • async

    非同期か同期かboolean値で指定します。

    デフォルトではtrueです。

  • timeout

    タイムアウト値を設定します。

    単位は秒です。

    タイムアウト発生時にはonTimeoutで設定した関数を実行します。

  • responseType

    レスポンスタイプを設定します。

    設定できるレスポンスタイプは以下です。

    • RESPONSE_TYPE_XML : XML形式。
    • RESPONSE_TYPE_JSON : JSON形式。JSON形式ではevalした結果をコールバック関数に返します。
    • RESPONSE_TYPE_TEXT : TEXT形式。
    • RESPONSE_TYPE_HTML : HTML形式。

    デフォルトはJSON形式です。

通信状態ごとの関数実行

Kumu.AjaxではAjaxの通信状態に合わせ関数を実行することができます。

状態は以下です。

  • Uninitialized : 初期かされていない状態です
  • Loading : 通信開始の状態です
  • Loaded : 通信完了の状態です
  • Interactive : レスポンスを受け取れる状態です
  • Failure : 通信失敗の状態です
  • Exception : javascriptエラー発生の状態です
  • Timeout : タイムアウト発生の状態です

これらの状態に合わせ関数を設定するにはAjaxComponentのキーに'on'+状態名で関数をセットします。

var ajax = Kumu.Ajax.getS2AjaxComponent();

ajax.url = '/hogehoge.do';

var func1 = function(request, component){
  alert('loading');
};

var func2 = function(request, component){
  alert('loaded');
};

// Loading中、Load完了時にalert
ajax.params = {'hoge':1, 'foo':2, onLoading : func1, onLoaded : func2};

ajax.doAction = function(response) {
};
Kumu.Ajax.executeAjax(ajax);

各関数は以下の引き数を渡されて実行されます。

  • XMLHTTPRequest
  • AjaxComponent

また通信状態ごとの関数の指定方法にはもうひとつの方法があり、コールバック関数のpropertyに設定することができます。

コールバック関数ごとに動作を切り替えるたい場合に使用します。

var ajax = Kumu.Ajax.getS2AjaxComponent();

ajax.url = '/hogehoge.do';

var func1 = function(request, component){
  alert('loading');
};

var func2 = function(request, component){
  alert('loaded');
};

// Loading中、Load完了時にalert
ajax.params = {'hoge':1, 'foo':2};

var callback = function(response){
};

callback.onLoading = func1;
callback.onLoaded = func2;

ajax.doAction = callback;
Kumu.Ajax.executeAjax(ajax);

Teedaとの連携

Kumu.AjaxはTeedaとの連携を簡単に行う事が出来ます。

executeTeedaAjaxを使うと簡単にS2のコンポーネントを呼び出す事が出来ます。

// 呼び出したいコンポーネント名 + "_" + 呼び出したいメソッド名
function hoge_foo(response){
}

Kumu.Ajax.executeTeedaAjax(hoge_foo, {"パラメータ名" : "パラメータ値"});

executeTeedaAjaxはコールバック関数を解析し、名前からコンポーネント名、メソッド名を取得します。

そのため無名関数では正しく動作しないので注意して下さい。

その他の詳細はTeeda Ajaxを参照して下さい。

executeTeedaAjaxを使用する際にも上記の通信状態による関数実行は使用できます。

executeTeedaAjaxに渡すパラメータに同様に追加して下さい。

JSONレンダリング

Kumu.AjaxではJSONをHTMLテンプレートにはめ込みレンダリングする事が出来ます。

Kumu.Ajax.render関数はJSONのキーとHTMLのidをマッチングさせレンダリングを行います。

マッチした要素のinnerHTMLにJSONの値を出力します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script language="JavaScript" type="text/javascript" src="./js/ajax.js"></script>
<script>
var o = {
  'test' : 'てすと',
  'test1' : 'てすと1',
  'test2' : [
  {
    'no':1,
    'name' : 'name1'
  },
  {
    'no':2,
    'name' : 'name2'
  },
  {
    'no':3,
    'name' : 'name3'
  },
  {
    'no':4,
    'name' : 'name4'
  },
  {
    'no':5,
    'name' : 'name5'
  }]
}

</script>

<title>JSON Rendering Sample</title>
</head>
<body>
<div id='test' style="display:none">Test</div>
<div id='test1' style="display:none">Test</div>
<div id='test1' style="display:none">Test</div>

<table border="1">
  <tr>
    <td>-</td>
    <td>No</td>
    <td>Name</td>
  </tr>
  <tr id='test2' style="display:none">
    <td>Rendering</td>
    <td id="no">Test</td>
    <td id="name">Test</td>
  </tr>
</table>
<input type="button" value="RENDER" onclick="Kumu.Ajax.render(o);">
</body>
</html>

結果は以下のようになります。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script language="JavaScript" type="text/javascript" src="./js/ajax.js"></script>
<script>
var o = {
  'test' : 'てすと',
  'test1' : 'てすと1',
  'test2' : [
  {
    'no':1,
    'name' : 'name1'
  },
  {
    'no':2,
    'name' : 'name2'
  },
  {
    'no':3,
    'name' : 'name3'
  },
  {
    'no':4,
    'name' : 'name4'
  },
  {
    'no':5,
    'name' : 'name5'
  }]
}

</script>

<title>JSON Rendering Sample</title>
</head>
<body>
<div id="test" style="">てすと</div>
<div id="test1" style="">てすと1</div>
<div id="test1" style="">てすと1</div>
<table border="1">
<tbody>
<tr>
  <td>-</td>
  <td>No</td>
  <td>Name</td>
</tr>
<tr id="test2:rendered" style="">
  <td>Rendering</td>
  <td id="no:rendered">1</td>
  <td id="name:rendered">name1</td>
</tr>
<tr id="test2:rendered" style="">
  <td>Rendering</td>
  <td id="no:rendered">2</td>
  <td id="name:rendered">name2</td>
</tr>
<tr id="test2:rendered" style="">
  <td>Rendering</td>
  <td id="no:rendered">3</td>
  <td id="name:rendered">name3</td>
</tr>
<tr id="test2:rendered" style="">
  <td>Rendering</td>
  <td id="no:rendered">4</td>
  <td id="name:rendered">name4</td>
</tr>
<tr id="test2:rendered" style="">
  <td>Rendering</td>
  <td id="no:rendered">5</td>
  <td id="name:rendered">name5</td>
</tr>
<tr id="test2" style="display: none;">
  <td>Rendering</td>
  <td id="no">Test</td>
  <td id="name">Test</td>
</tr>
</tbody>
</table>
<input type="button" onclick="Kumu.Ajax.render(o);" value="CHANGE"/>
</body>
</html>

render関数ではレンダリングする要素のstyleがdisplay:noneである場合には表示するように処理を行います。

またidのobjectがArrayである場合にはその要素をコピーし繰り返しArrayのサイズ分レンダリングします。

renderで新たに追加された要素はid + "rendered"というidを持っています。

新たに追加された要素を削除する場合にはKumu.Ajax.removeRender(id)で削除することができます。

Formの値の取得

Kumu.AjaxはFormの値を取得するためのヘルパーを用意しています。

Kumu.FormHelperを使うとFormをJSON化でき、簡単に値を取得する事ができます。

では簡単な見てみます。

<form id="Form">
  <input type="text" name="firstName"/>

  <input type="text" name="lastName"/>
</form>

上記のFormはname属性がfirstNameとlastNameという名前のinputフィールドを持っています。

このFormをJSON化し、値を取得するには以下のように記述します。

// FormをJSON化する
var form = Kumu.FormHelper.create('Form');

//name属性がfirstNameの値を取得
var firstNameValue = form['firsrtName']

//name属性がfirstNameの値を取得
var lastNameValue = form['lastName']

FormをJSON化するのはKumu.FormHelper.createを使用します。

FormHelperの引き数にはFormの要素あるいは対象のFormのid属性の値を指定します。

Kumu.FormHelper.create(<Form要素もしくはFormのid属性>, <タイプ>);

Formのタイプ

FormHelperはいくつかのタイプをサポートしています。

タイプは以下の3つです。

  • 'r' rawモード -- Formそのままのname属性を使用してJSONを構築する。(デフォルト)
  • 't' teedaモード -- FormをTeedaのPageクラスのidのようにJSONを構築する。
  • 'i' idモード -- Formのname属性ではなくid属性をキーに使用してJSONを構築する。

Teedaモードを使用するには以下のように記述します。

Kumu.FormHelper.create('Form', 't');

rawモード

rawモードはそのままname属性の値をキーとしてJSONを構築します。

デフォルトではこの動作になります。

Kumu.FormHelper.create('Form');

teedaモード

teedaモードはteedaでレンダリングされたFormをJSON化します。

teedaはJSF実装FWのためFormをレンダリングするとname属性がそのまま出ないケースなどがあります。

例えばItemsのケースです。

<form id="Form">
<input type="text" id="num1" class="hoge"/><br/>

<input type="text" id="num2"/><br/>
<span id="str">aaa</span>
<input type="hidden" id="fooItemsSave" />

<table border="1">
       <div id="fooItems">
       <tr>
         <td><span id="fooNo">100</span></td>

               <td><input type="text" id="aaa" title="AAA" /></td>
               <td><input type="text" id="bbb" title="BBB" /></td>

       </tr>
       </div>
</table>
<input type="submit" id="doNothing" />
</form>

このケースの場合、idは同じになってしまうためidで取得するのは難しく、またname属性は複雑な値になり解析が困難です。

このようなケースもKumu.FormHelperを使用することができます。

var form = Kumu.FormHelper('Form', 't');
var items = form['fooItems']
for(var i = 0; i < items.length; i++){
    var item = items[i];
    alert('aaa = '+item['aaa']+' bbb = '+item['bbb');
}

Teedaモードを使うと上記のように繰り返し部分もリスト化され、簡単にアクセスすることができます。

idモード

id属性の値をキーとしてJSONを構築します。

その他の動作はrawモードと変わりません。

JSONの文字列化(この機能は将来kumu.jsに移行します)

Kumu.JSONSerializerを使うとJSONを文字列化することができます。

var form = Kumu.FormHelper.create('aForm');

// Kumu本体のログ機能でログ出力
Kumu.log(Kumu.JSONSerializer.serialize(form));

上記のようにFormの内容などをデバッグする際に使用することができます。

またobjectであればなんでも文字列化することができます。

応用

JSONSerializerを使用すると複数のobjectをまとめて文字列にする事ができます。

そのためAjaxで送信するパラメータも減らすことができます。

JSON化した文字列はサーバサイドでorg.seasar.teeda.ajax.JSONSerializerを使用してMapに復元することができます。

String str = "{'test1':'test2'}";
Map map = JSONSerializer.evalMap(str);

Mapに変換後、Dxoなどを使用することによって簡単に好きなDtoなどにマッピングする事が出来るようになります。

リファレンス

Kumu.Ajax.executeAjax(ajaxComponent)

Ajaxで通信を行います。

詳細はAjaxによる非同期通信を参照して下さい。

Kumu.Ajax.executeTeedaAjax(function, object)

Ajaxで通信を行います。

S2のコンポーネントと連携します。

詳細はTeeda Ajaxを参照して下さい。

Kumu.Ajax.render(json)

JSONをレンダリングします。

詳細はJSONレンダリング を参照して下さい。

Kumu.Ajax.removeRender(id)

Kumu.Ajax.render(json)で新たに追加された要素を削除します。

Kumu.FormHelper.create(element, type)

FormをJSON化します。

詳細は.. Formの値の取得 を参照して下さい。

Kumu.FormHelper.getValue(element)

指定した要素の値を取得します。

Kumu.FormHelper.getItem(element)(Teeda使用時)

指定した要素が含まれているItemsの中のItemを返します。

Itemsのリストの中に入っているItemのJSONを返します。

Kumu.FormHelper.getItemsIndex(form, element)(Teeda使用時)

指定した要素が含まれているItemsのIndexを返します。

Kumu.JSONSerializer.serialize(object)

指定したobjectをJSON文字列化します。