Drupal 7 における AJAXフォームとは、ページをリロードすることなく動的に変化させるようなフォームのことで、簡単に生成、操作することが出来ます。これは Drupal のフォームAPI のシンプルな拡張機能です。
動的に変化するフォームとは何でしょう?従来のウェブでは、ユーザーがフォームに入力して送信ボタンを押すと、ページ全体が再構築されてブラウザに送られてきました。AJAX フォームでは、ページ全体を再読み込みすることなく、ページの一部、又はフォームの一部だけが更新されたり、他の要素と置き換えられます。つまり変更箇所だけがその場で変更されます。これはユーザーにとって扱いやすく、一般的にはページ全体を再読み込みするより速いです。
AJAX についての事実:
いくつかの背景
動作の概観は次のようになります。
AJAX 対応のフォームを作るには次のようにします。
Example モジュールの「AJAX Example: generate checkboxes」の例では、AJAX を利用するフォーム要素は $form['howmany_select'] というセレクトボックスで、これは 'checkboxes-div' という ID を持つHTML 要素(#ajax['wrapper'] で指定されている、$form['checkboxes_fieldset'] フィールドセットのラッパー)を置き換えます。
<?php
/**
* AJAX のセレクトボックスの操作に応じて、チェックボックスのフィールドセット部分を置き換えます。
*/
function ajax_example_autocheckboxes($form, &$form_state) {
$default = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1;
$form['howmany_select'] = array(
'#title' => t('How many checkboxes do you want?'),
'#type' => 'select',
'#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),
'#default_value' => $default,
'#ajax' => array(
'callback' => 'ajax_example_autocheckboxes_callback',
'wrapper' => 'checkboxes-div',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['checkboxes_fieldset'] = array(
'#title' => t("Generated Checkboxes"),
// prefix/suffix で置換対象の div 要素を設定します。
// これは上記の #ajax['wrapper'] で指定したものです。
'#prefix' => '<div id="checkboxes-div">',
'#suffix' => '</div>',
'#type' => 'fieldset',
'#description' => t('This is where we get automatically generated checkboxes'),
);
// 完全なコードは以下に!
?>'howmany_select' 要素が変更されると、バックグラウンドでサーバーとの非同期通信が行われ、フォームが再構築されます。'howmany_select' の値をもとにフォームが再構築された後、コールバック関数がコールされます。
<?php
/**
* 返り値はフォームの変更された部分のみです。
* #ajax['callback'] は、HTMLかレンダー配列、もしくはコマンドの配列をフォームの一部として返します。
*/
function ajax_example_autocheckboxes_callback($form, $form_state) {
return $form['checkboxes_fieldset'];
}
?>このケースでは、コールバックは HTMLページの中で置き換え対象であるフォームの一部だけを返します。このあとレンダリングされた文字列がページに返され、#ajax['wrapper'] で指定した部分と置き換えられます。
これが AJAX フォームの動作の概観です。#ajax プロパティーの設定されたフォーム要素は、それがクリックされるか、変更された際に、そのアクションをトリガーとしてバックグラウンドでサーバーとの通信を行います。サーバー側では、フォームビルダー関数によってフォームが再構築され、#ajax['callback'] で指定されたコールバック関数がコールされます。コールバック関数はオリジナルページの代替部分として、再構築されたフォームの一部を返します。
上述の Example モジュールの例について、もう少し詳しく見てみましょう。(Example モジュールは現在もちゃんとメンテナンスがなされ配布されています。ダウンロードして実際にどのように動作するかを見ることができます。)
<?php
/**
* AJAX のセレクトボックスの操作に応じて、チェックボックスのフィールドセット部分を置き換えます。
*/
function ajax_example_autocheckboxes($form, &$form_state) {
$default = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1;
$form['howmany_select'] = array(
'#title' => t('How many checkboxes do you want?'),
'#type' => 'select',
'#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),
'#default_value' => $default,
'#ajax' => array(
'callback' => 'ajax_example_autocheckboxes_callback',
'wrapper' => 'checkboxes-div',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['checkboxes_fieldset'] = array(
'#title' => t("Generated Checkboxes"),
// prefix/suffix で置換対象の div 要素を設定します。
// これは上記の #ajax['wrapper'] で指定したものです。
'#prefix' => '<div id="checkboxes-div">',
'#suffix' => '</div>',
'#type' => 'fieldset',
'#description' => t('This is where we get automatically generated checkboxes'),
);
$num_checkboxes = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1;
for ($i=1; $i<=$num_checkboxes; $i++) {
$form['checkboxes_fieldset']["checkbox$i"] = array(
'#type' => 'checkbox',
'#title' => "Checkbox $i",
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
/**
* 返り値はフォームの変更された部分のみです。
* #ajax['callback'] は、HTMLかレンダー配列、もしくはコマンドの配列をフォームの一部として返します。
*/
function ajax_example_autocheckboxes_callback($form, $form_state) {
return $form['checkboxes_fieldset'];
}
?><?php $elements['some_element']['#markup'] = 'New markup.'; return $elements; ?>#attributes プロパティにすでに変換されている値を変更する際は、$form の配列も深く掘り下げ、対応する要素のプロパティーも同様に変更してください。
<?php // 両方必要です。 $elements['some_element']['#disabled'] = TRUE; $elements['some_element']['#attributes']['disabled'] = 'disabled'; return $elements; ?>
ブラウザがJavaScriptに対応していない場合の対処法を考えてみましょう。AJAXフォームはこのために構築されましたが、JavaScriptが有効/無効の両方の環境で、フォームを簡単に、そして正確に動作させるには、かなりの労力がかかることがあります。多くの場合、非同期通信を行う要素には「次へ」ボタンが設置されます。ボタンが押されると、要素の値が変更されたときと同様に、ページ(フォーム)が再構築されます。Examples モジュールは ajax_example_graceful_degradation.inc ファイルでこのようないくつかの例を提供しています。
AJAX Framework では、基本的なフォームの動作に加えて、たくさんの機能やオプションを提供しています。