Drupalのモジュール(ctools)でのajaxポップアップ(modal)作成の基本
今回、画面でポップアップでデータ入力、ajaxでデータを更新することを試みたいですが、jQuery、Bootstrapなどのmodalライブラリで実現ができます。但しDrupalサイトでポップアップを作るとしたら、やはりctoolsのModal機能を利用してみたいです(ctools(Chaos tool suite)はDrualの開発によく利用されているAPI)。
やりたいこと:ポップアップを立ち上げて入力したデータをajaxでサーバーと交信
- ポップアップ(modal)の作成
- データ入力フォームの表示
- 入力されたデータをajaxでサーバーに送信、データ更新

ポップアップ作成の流れの基本:ctoolsのmodal.jsを利用します
- ポップアップを開くリンク/ボタンの作成
- ctoolsのmodal.js、modal.cssをこのページに入れる(ajaxで操作するため)
- ポップアップのリンク/ボタンがクリックされた、ポップアップが開く
- ポップアップのフォームにデータ入力、送信ボタンクリック
- 入力されたデータをサーバーにajaxで送信、データ更新される

ctoolsのmodal利用の問題点
- ctoolsのmodal利用に関する紹介はウェブ上にたくさんあります。また、インストールされたctools(modules\ctools\ctools_ajax_sample\ctools_ajax_sample.module)にサンプルプログラムもあります
- 問題点1:ポップアップに表示されるフォームはjavascriptでhtmlコードとして吐き出されています(modules\ctools\ctools_ajax_sample\js\ctools-ajax-sample.js)
- 簡単なフォームに問題はないが、複雑なフォームに煩雑になります
- 問題点2:ポップアップウィンドウに関する設定はphpソースコード内で定義
- ロジックとUI設定を分離しべき、ポップアップに関する設定はcss、jsに任せるべき
ctoolsのmodal利用の改善
- 上記問題1は、DrupalのForm APIを利用して、フォーム作成を行います
- 上記問題2は、ポップアップの外観はサイト全体のテーマ(bootstrap)に統一し、背景、フォントサイズなどはcssファイルで個別に設定します
ポップアップの作成
- ポップアップを起動するリンク/ボタンの作成は省略します
- ポップアップとの通信URLをhook_menuで作成
$items['my-module/%ctools_js/add'] = array(
'page callback' => 'my_module_callback',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
- URLの設定に「%ctools_js」部分があります。ここで、'nojs'の定数を入力する必要はあります。例:http://your-site/my-module/nojs/add
- ポップアップの起動リンク/ボタンのクラス属性: class="ctools-use-modal"をセットします(これがないと、Modalポップアップの起動はできないです)
- ページのコールバック関数(my_module_callback)の作成
function my_module_callback($ajax) {
if ($ajax) {
// ctoolsのajax、modalに関するjsファイルをクライアントへ
ctools_include('ajax');
ctools_include('modal');
//フォーム作成に関する上方
$form_state = array(
'ajax' => TRUE,
'title' => t('New Group Creation'),
);
//ポップアップフォームの作成
//フォームからの更新データを$form_stateにセットする
$output = ctools_modal_form_wrapper('my_module_form', $form_state);
//新規ポップアップにajaxが有効にする
if (!empty($form_state['ajax_commands'])) {
$output = $form_state['ajax_commands'];
}
//ポップアップの出力
print ajax_render($output);
drupal_exit();
}
else {
return drupal_get_form('mymodule_form');
}
}
// ポップアップにある入力フォームの定義
function my_module_form($form, $form_state) {
$form = array();
$form['new_link_text'] = array(
'#type' => 'textfield',
'#title' => t('Group Name'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
// データ更新
function my_module_form_submit(&$form, &$form_state) {
// データの更新
// ロジックは省略
// ポップアップを閉じるコマンド
$form_state['ajax_commands'][] = ctools_modal_command_dismiss();
}
- 注目すべき関数の役割: ctools_modal_form_wrapper
- 定義されたフォーム(my_module_form)をレンダリング可能にする
- ajaxからのデータ送信情報を$form_stateに設定
- hook_form_submitなどの起動