Drupalのモジュール(Ctools)がAPIモジュールであり、幅広く使用されている
- Drupalのモジュール(Ctools)がAPIモジュールなので、直接に利用するのではなく、いろいろなモジュールに使用されています
- 例:Views、PanelsなどがCtoolsを利用しています
- 主な機能は以下のようです(Drupalの中核な存在です)
- Plugins
- Exportables
- AJAX responder
- Form tools
- Object caching
- Contexts
- Modal dialog
- Dependent
- Content
- Form wizard
- CSS tools
CtoolsのDependent(依存)がフォーム要素を表示/非表示されるダイナミックな変化に使用されます
- ダイナミックフォーム: フォーム要素がある条件で表示、非表示を行います
- CtoolsがFormAPIにプロパティ("#dependency")をプラグインしています
// 1. Include CTools Dependent helper ctools_include('dependent'); $form['select_set'] = array( '#type' => 'fieldset', '#title' => t('Selectbox Set'), ); $form['select_set']['restrict_by'] = array ( '#title' => t('選択してください'), '#type' => 'select', '#options' => array ( 'none'=>t('Select one'), 'trip'=>t('旅行'), 'month'=>t('カレンダー'), ), '#default_value' => array('none'), ); $form['select_set']['trips'] = array ( '#type' => 'select', '#title' => t('旅行'), '#options' => array ( 'trip1' => t('地中海クルーズ'), 'trip2' => t('南極旅行'), ), // セレクトが「旅行」の場合にこのエレメントが表示される '#dependency' => array('edit-restrict-by' => array('trip')), ); $form['select_set']['months'] = array ( '#type' => 'select', '#title' => t('カレンダー'), '#options' => array ( '1' => t('一月'), '2' => t('二月'), //...and so on ), // セレクトが「カレンダー」の場合にこのエレメントが表示される '#dependency' => array('edit-restrict-by' => array('month')), );
- フォームの構成はDrupalのFormAPIに従っています
- 制御される要素は"#dependency"プロパティで記述されています
Ctoolsの"#depencency"の要素識別方法にラジオボタンが特別に扱われています
- 制御要素が先に定義します(例:セレクトボックス:(restrict_by)
- 制御される要素が二つ:trip、month セレクトボックス
- 制御される要素の"#dependency"設定より制御要素の状態で要素の表示/非表示がjavascriptで操作されます
- "#dependency"の定義は配列で行います
”#dependency” => array( "依存先要素のID" => "依存先要素の状態" )
- 例:依存先は「セレクトボックス」(restrict_by)とします
- 依存先(restrict_by)のid(htmlソースにある要素id):edit-restrict-by
- 依存先の状態: none/trip/month 三種類です。
- trip、またはmonthが選ばれたら、旅行、またはカレンダーのセレクトボックスを表示させる(選ばれなかったら、表示させない)
- 但し、制御要素がラジオボタン("radios")の場合に"依存先要素のID"書き方が変わります
'#dependency' => array('radio:restrict_by' => array('trip')), // radio: 決まり文言 // restrict_by: 要素ID
- 特に、ラジオボタンの要素IDはhtml上の要素IDではありません。FormAPIで定義する要素のIDです
- "依存先要素の状態"は要素の性質より変わります
- ラジオボタン: FormAPIの"radios"での"#opetions"に選択された要素のキー:none/trip/month の一つ
'#dependency' => array('edit-restrict-by' => array('month')),
- セレクトボックス: FormAPIの"select"での"#opetions"に選択された要素のキー:none/trip/month の一つ
'#dependency' => array('edit-restrict-by' => array('trip')),
- チェックボックス: html上に各チェックボックスIDごとに、チェックされた(true:1)かチェックされていない(false:0)の一つ
'#dependency' => array('edit-restrict-by-month--2' => array(true)),
- ラジオボタン: FormAPIの"radios"での"#opetions"に選択された要素のキー:none/trip/month の一つ
- 今回テスト(セレクトボックス/チェックボックス/ラジオボタン)したソースは以下のとなります
function example_page($form, &$form_state){ // 1. Include CTools Dependent helper ctools_include('dependent'); $form['select_set'] = array( '#type' => 'fieldset', '#title' => t('Selectbox Set'), ); $form['select_set']['restrict_by'] = array ( '#title' => t('選択してください'), '#type' => 'select', '#options' => array ( 'none'=>t('Select one'), 'trip'=>t('旅行'), 'month'=>t('カレンダー'), ), '#default_value' => array('none'), ); $form['select_set']['trips'] = array ( '#type' => 'select', '#title' => t('旅行'), '#options' => array ( 'trip1' => t('地中海クルーズ'), 'trip2' => t('南極旅行'), ), // セレクトが「旅行」の場合にこのエレメントが表示される '#dependency' => array('edit-restrict-by' => array('trip')), ); $form['select_set']['months'] = array ( '#type' => 'select', '#title' => t('カレンダー'), '#options' => array ( '1' => t('一月'), '2' => t('二月'), //...and so on ), // セレクトが「カレンダー」の場合にこのエレメントが表示される '#dependency' => array('edit-restrict-by' => array('month')), ); $form['radio_set'] = array( '#type' => 'fieldset', '#title' => t('Selectbox Set'), ); $form['radio_set']['restrict_by'] = array ( '#title' => t('選択してください'), '#type' => 'radios', '#options' => array ( 'none'=>t('Select one'), 'trip'=>t('旅行'), 'month'=>t('カレンダー'), ), '#default_value' => 'none', ); $form['radio_set']['trips'] = array ( '#type' => 'select', '#title' => t('旅行'), '#options' => array ( 'trip1' => t('地中海クルーズ'), 'trip2' => t('南極旅行'), ), '#dependency' => array('radio:restrict_by' => array('trip')), ); $form['radio_set']['months'] = array ( '#type' => 'select', '#title' => t('カレンダー'), '#options' => array ( '1' => t('一月'), '2' => t('二月'), //...and so on ), '#dependency' => array('radio:restrict_by' => array('month')), ); $form['Checkbox_set'] = array( '#type' => 'fieldset', '#title' => t('Checkbox Set'), ); $form['Checkbox_set']['restrict_by'] = array ( '#title' => t('選択してください'), '#type' => 'checkboxes', '#options' => array ( 'trip'=>t('旅行'), 'month'=>t('カレンダー'), ), ); $form['Checkbox_set']['trips'] = array ( '#type' => 'select', '#title' => t('旅行'), '#options' => array ( 'trip1' => t('地中海クルーズ'), 'trip2' => t('南極旅行'), ), // チェックボックスのIDが変わったので注意が必要 '#dependency' => array('edit-restrict-by-trip--2' => array(true)), ); $form['Checkbox_set']['months'] = array ( '#type' => 'select', '#title' => t('カレンダー'), '#options' => array ( '1' => t('一月'), '2' => t('二月'), //...and so on ), '#dependency' => array('edit-restrict-by-month--2' => array(true)), ); return $form; }
Ctoolsの依存(dependent)が表示/非表示制御のみ、FormAPIのstatesより制御範囲が狭いです
- FormAPIに"#dependency"プロパティをプラグインは、表示/非表示のみとなります
- FormAPIのstatesプロパティの制御と比較すると、制御できる範囲は狭いです
- FormAPIのstatesプロパティは、表示/非表示/collapse/extended/enabled/disabledなどの制御ができます
感想と結論:Ctoolsの依存(dependent)の設定、コーティングルールに統一性が足りなく、わかりずらいです
- 依存性の設定定義にラジオボタンの特別扱いを認識しなければならない(最初は戸惑いがあるだろう)
- これらの特別なコーティングルールを覚える必要があります
- 要素特定にはjQueryを利用していない
- 比較してみると、FormAPIの”#states”プロパティの使用で、より統一性があり、柔軟性のダイナミックフォーム作成ができます