Ajaxヘルパー
remote_function()は、symfonyのアクションによってページの一部に変更の必要が生じた場合に、それを実現します。Ajaxの中心とも言えるヘルパーです。
<?php echo javascript_tag( remote_function(array( 'update' => 'mynews', 'url' => 'mymodule/myaction', )) ) ?>
これは、mymoduleモジュールのmyactionアクションの結果によってid属性がmynewsの部分を更新します。
この種のヘルパー群はいろいろ用意されてるので、以下に代表的なものを表にしておきます。
| ヘルパー | 説明 |
| link_to_remote() | リンク時の更新 |
| form_remote_tag() | フォームによる更新 |
| submit_to_remote() | サブミットによる更新(通常のフォームタグ内でAjaxによるサブミットを行う場合に使用する。JavaScript有効/無効の場合分けで通常のサブミットと使い分ける時など有効) |
| observe_field() | サブミット時ではなく、フィールドの値が更新された際に反応 |
| observe_form() | フォームフィールドのどれか一つが更新されれば反応 |
| periodically_call_remote() | 一定時間ごとにバックグラウンドで通信を行う(フォームの自動保存やマウス位置の追跡などに有効) |
update_element_function()が出力します。最初の例のように、Ajaxヘルパーには配列を渡します。これらに代入する配列の要素についても表にしておきます。
| ヘルパー | 説明 |
| update | 更新する箇所のid属性 |
| url | 更新内容の元となるアクションのURL |
| with | 観察対象となっているフィールドの値以外に何かを渡したい時、これを用いて記述する(JavaScript表現)。サンプル参照 |
| position | before/after/top/bottomを設定して、それぞれ更新位置として要素の前/後/最前部/最後部を設定(top/bottomは、購入リスト等要素の内容が複数ある場合に用いる) |
| confirm | 送信前にユーザーに確認のメッセージ |
| condition | ブラウザ側で行われるテスト(JavaScript)によってリモート関数を条件付ける。「'condition' => "$('elementID') == true",」なら、「$('elementID')」(Prototypeの関数で、document.getElementById("elementID");と同義)が要素を返せばAjaxヘルパーが実行される |
| method | get/postのリクエストメソッドを指定 |
| script | 'true'を設定すると、アクション応答がJavaScriptを含む場合それが実行される(デフォルトではセキュリティ上の理由で実行されない) |
| frequency | 更新間隔を設定(periodically_call_remote, observe_field, observe_form特有のオプション。デフォルトは10秒) |
コールバック
さて、今まで挙げたAjaxヘルパーなどによる実行状況如何はコールバックを指定することで知ることができ、その際の動作も設定できます。これらは先程同様に、配列の要素としてAjaxヘルパーに渡します。以下にコールバックを表で示します。
| ヘルパー | 説明 |
| before | リクエスト初期化前 |
| after | リクエスト初期化直後かつロードされる前 |
| loading | リモートレスポンスがブラウザにロードされている最中 |
| loaded | リモートレスポンスをブラウザがロード完了した時 |
| interactive | ロードが終了してなくともユーザーがリモートレスポンスにインタラクト可能である時 |
| success | XMLHttpRequestが完了し、HTTPステータスコードが2XX(成功)の時 |
| failure | XMLHttpRequestが完了し、HTTPステータスコードが2XXでない時 |
| 404 | リクエストが404を返した時 |
| complete | XMLHttpRequestによる非同期通信が完了した時(success/failureに関係なく) |
例えば、
<?php echo link_to_remote('記事を削除する', array( 'update' => 'item', 'url' => 'post/delete?id='.$post->getId(), 'loading' => "Element.show('item')", 'complete' => "Element.hide('item')", )) ?>
は、リモートリクエスト初期化の際、ロード中にitemの部分(「通信中」など)を見せ、一旦リクエストが完了したら隠すということを行います。
show、hideはPrototypeの関数です。その他視覚効果など:script.aculo.us
symfonyはscript.aculo.usライブラリの視覚効果も統合しています。
Effect.Highlight('id_of_element', {startcolor:'#ffff99', endcolor:'#ffffff'})

Effect.BlindDown('id_of_element');

Effect.Fade('id_of_element',
{ transition: Effect.Transitions.wobble })

また、これらEffectオブジェクトをカプセル化し同様のJavaScriptを出力するvisual_effect()というJavaScriptヘルパーがあり、先程のコールバックで利用することが可能です。以下に、今回のサンプルの一部を示します。
<?php echo form_remote_tag(array( 'update' => 'hyouji', 'url' => 'ajax_test/namae', 'complete' => visual_effect('highlight', 'hyouji'), (XMLHttpRequestが完了したときに、結果をハイライト表示する) )) ?>

他にも次のようなヘルパーが利用できます。詳しくはDefinitive Guideを参照してください。
input_auto_complete_tag()draggable_element()/drop_receiving_element()sortable_element()input_in_place_editor_tag()
JSON
1回の更新で2つ以上のエレメントを更新したい場合などは、JSONが有効です。第1回で紹介した「sfView::HEADER_ONLY」と組み合わせて、アクションクラス中で次のように使用します。
class publishingActions extends sfActions { public function executeRefresh() { $output = '[["CPU", "i586"], ["OS", "Linux"]]'; (ここで2つの要素を設定している) $this->getResponse()->setHttpHeader("X-JSON", '('.$output.')'); (X-JSONヘッダーを設定する) return sfView::HEADER_ONLY; (ヘッダーのみ出力する) }
