アイキャッチ画像: デスクの上でパソコンを使用している

本日は「 Drupal 7 Ajax 入門」と題して、 Drupal (ドルーパル)で Ajax 処理を行う方法をご紹介できればと思います。

Drupal で Ajax 処理を実現する方法としては次の 2 通りの方法があります。

  1. Drupal の Form API を使う方法
  2. Drupal の Form API を使わない方法

Drupal の Form API ( Web フォーム処理のための API )には Ajax のための機能がデフォルトで備わっており、それを使うとかんたんに Ajax 処理を実現することができます。 もちろん、 Form API を使わない方法も可能となっていて、その場合は jQuery などを使った一般的な方法をとる形になります。

jQuery などを使った一般的な方法は解説記事や書籍もたくさんあるため、今回は前者の「 Drupal の Form API を使う方法」をご紹介したいと思います。

本題に入る前にまずは前提から。

前提

  • Drupal のバージョン: Drupal のバージョンは Drupal 7 。 Ajax の実現方法はバージョンによって少しずつ異なるのでご注意ください。
  • 想定読者: 想定読者はプログラマもしくは JavaScript / jQuery のわかるデザイナーの方。 CMS やフレームワークで Web 開発を行ったことのある方であれば、Drupal 開発者の方でなくても全体の流れ・感じはつかんでいただけるかと思います。

Drupal で Ajax - Form API を使った方法

では具体的に Drupal で Ajax を実現する方法をご紹介したいと思います。

今回は次のようなテキストフィールドと送信ボタンを備えたシンプルなフォームを作成してみましょう。 テキストフィールドに名前を入力して送信すると、ページ全体のロードなしにその下にある「こんにちは」の後ろに名前が追加されるという機能を作ります。

Drupal Form API を使った Ajax フォーム サンプル成果物

Drupal の Form API を使えば、定番的な処理は JavaScript を一切書かなくても実装することが可能です。 必要な手順は次のとおりです。

  1. フォームを作成する
  2. フォームに Ajax の設定を追加する
  3. Ajax リクエストに応えるコールバックを作成する

1. フォームを作成する

まずはフォームを作成します。 Drupal のページ作りの基本どおり、 hook_menu() とコールバック関数を作成します。

今回は umiajax という名前のカスタムモジュールを使います。 カスタムモジュールの作り方については以下の記事などを参考にしてみてください。

まずは hook_menu() 側から。

/**
 * Implements hook_menu().
 */
function umiajax_menu() {
  $items['umi/sample-form'] = array(
    'title' => 'Ajax form sample',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('umiajax_sample_form'),
    'access arguments' => array('access content'),
  );

  return $items;
}

ここでは hook_menu() の詳細の説明は割愛しますが、ここでは「パス umi/sample-form にアクセスがあった場合に関数 umiajax_sample_form() にページを描画させる」という設定を行っています。

続いて関数 umiajax_sample_form() を作成し、フォームを生成するコードを記述します。

/**
 * Implements hook_form().
 */
function umiajax_sample_form($node, &$form_state) {
  $form = array();

  // 名前入力フィールド
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Who are you?'),
  );

  // 名前を挿入する先の div 
  $form['greeting'] = array(
    '#type' => 'markup',
    '#markup' => $greeting,
    '#prefix' => '
', '#suffix' => '
', ); // サブミットボタン $form['submit'] = array( '#type' => 'submit', '#value' => '名前を送信', ); return $form; }

以上でフォームが表示できるようになりました(ちなみに hook_menu() への変更を反映させるにはキャッシュクリア(メニューのリビルド)が必要です)。

2. フォームに Ajax の設定を追加する

続いて上記フォームに Ajax の設定を追加します。 サブミットボタンの部分を次のとおり変更します。

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => '名前を送信',
    // Ajax のための設定を追加
    '#ajax' => array(
       'callback' => 'umiajax_sample_form_ajax_callback',
       'wrapper' => 'umiajax-greeting',
       'effect' => 'fade',
    ),
  );

ここで、 callback は非同期リクエストに対して JSON を返す関数wrapper はクライアント側に返ってきた JSON を HTML 化して挿入する先の DOM 要素の IDeffect は要素を挿入するときの視覚的なエフェクトのタイプを意味します。

3. Ajax リクエストに応えるコールバックを作成する

続いてコールバック関数 umiajax_sample_form_ajax_callback() を作成します。 こちらでは指定した DOM 要素に挿入したい内容を Drupal の通常のレンダーアレイの要領で返す必要があります。

function umiajax_sample_form_ajax_callback($form, $form_state) {
  return 'こんにちは' . check_plain($form_state['values']['name']) . 'さん';
}

ここでは、非同期リクエストが発生した時点でフォームの name フィールドに記入されている名前を加工した文字列を返すようにしています。 関数 check_pkain() は入力された内容をエスケープするための Drupal の関数です。

ここまで終われば、あとはキャッシュをクリアしてサイトのパス umi/sample-form にアクセスすれば Ajax 処理を行うフォームが利用できるはずです。

Drupal Form API を使った Ajax フォーム 動作イメージ

ただ、上記のやり方では非同期リクエストは 1 回きりしか利用できません。 繰り返し利用できるようにするためには、トリガとして使われた送信ボタンも含めた形で HTML 要素を置き換える必要があります。 具体的には上記の関数 umiajax_sample_form()umiajax_sample_form_ajax_callback() を次の形に変更すると、ページの再読み込みなしで何度でも Ajax 処理が利用できるようになります。

umiajax_sample_form():

/**
 * Implements hook_form().
 */
function umiajax_sample_form($node, &$form_state) {
  // フォームの中身をすべて置き換えるためにラッパでくるむ
  // Ajax リクエストの結果置き換え対象となるのは #umiajax-wrapper 全体
  $form = array(
    'wrapper' => array(
      '#prefix' => '
', '#suffix' => '
', ), ); // 名前入力フィールド $form['wrapper']['name'] = array( '#type' => 'textfield', '#title' => t('Who are you?'), ); // 名前を挿入する先の div $form['wrapper']['greeting'] = array( '#type' => 'markup', '#markup' => 'こんにちは', '#prefix' => '
', '#suffix' => '
', ); // 送信ボタン $form['wrapper']['submit'] = array( '#type' => 'submit', '#value' => '名前を送信', '#ajax' => array( 'callback' => 'umiajax_sample_form_ajax_callback', // フォームのラッパを置き換え対象とする 'wrapper' => 'umiajax-wrapper', 'effect' => 'fade', ), ); return $form; }

umiajax_sample_form_ajax_callback():

function umiajax_sample_form_ajax_callback($form, $form_state) {
  $form['wrapper']['greeting']['#markup'] = 'こんにちは' . check_plain($form_state['values']['name']) . 'さん';

  // フォームのラッパの部分をすべて返す
  return $form['wrapper'];
}

ここまでのところを押さえれば Ajax 処理はひととおりできるようになります。 実際のホームページで使う場合には JavaScript が動作しないときのためのフォールバックも考えておく必要があったりしますが、そのあたりはどちらかというと通常の Form API のお話になるのでまた機会を改めてご紹介できればと思います。

終わりに

以上です。 いかがだったでしょうか?

今回は Drupal 7 で Form API を使って Ajax 処理を行う方法をご紹介しました。 Drupal の優れた Form API のおかげで、 JavaScript を一切記述することなく PHP コードだけで Ajax 処理を実装できることを確認しました。

jQuery などを使用した一般的な方法でももちろん実装することはできますが、開発効率やコードのシンプルさ、わかりやすさという点では Drupal API を使った方法に大きなメリットがあります。 このあたりの API が充実しているところも、ホームページ開発に Drupal を選ぶべき大きな理由のひとつですね。

フォーム周りについては他にもさまざまな機能が用意されているのでそのあたりもまた機会を見つけてご紹介していきます。


共に働く新しい仲間を
募集しています

スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。