Drupalのフォーム(form)システムが既存のフォームに対して、任意の要素の追加、削除、変更手段が提供されています。システム全体の柔軟性が高くて、魅力が大きいところです。
「hook_form_alter」の実装で、既存フォームの変更ができるようになります。フォームの各要素の記述arrayを変更すれば、フォームの各要素が変えられます。
フォーム要素を追加する場合、既存要素の一番後ろに追加するのは、簡単に実現できますが、特定の要素の前・後にどう追加すれば少し悩みました。いろいろ調べてみましたが、方法としては二つあります。
- フォーム(form)記述子「#weight」(forms_api_referenceを参考)で追加した要素の表示順序を変えます。
- もし、既存の要素に「#weight」記述がなければ、これらの要素に「#weight」の記述を追加すればよいです。
- 「#weight」が小さいほど、前に表示されます
// 既存フォームに「name」と「last_name」要素があり
$form['name'] = array(
'#type' => 'fieldtext',
・・・・・
);
$form['last_name'] = array(
'#type' => 'fieldtext',
・・・・・
);
// hook_form_alterの実装で既存フォームの変更
function xxx_form_alter( &$form, &$form_state, $form_id ){
$new_ele['last name'] = array(
'#type' => 'fieldtext',
・・・・・
);
// 「#weight」の順序を書き直す
// 小さいほど先に表示される
$from['name']['#eight'] = 5;
$from['last_name']['#eight' ] = 10;
$from['first_name']['#eight' ] = 15;
}
- フォームの記述配列(array)に特定の場所を探し出して、配列の操作で新要素をそこに追加すればよいです
// 既存フォームに「name」と「last_name」要素があり
$form['name'] = array(
'#type' => 'fieldtext',
・・・・・
);
$form['last_name'] = array(
'#type' => 'fieldtext',
・・・・・
);
// hook_form_alterの実装で既存フォームの変更
function xxx_form_alter( &$form, &$form_state, $form_id ){
// 新要素記述の作成
$new_ele['last name'] = array(
'#type' => 'fieldtext',
・・・・・
)
// arrayの関数操作で$formの[name」要素の後に
//[last_name]要素を挿入する
$pos = array_search('name',array_keys($form)) +1;
array_splice($form, $pos,0, $new_ele ) ;
}
- 上記操作のイメージは以下のよう
- 上記[last_name]要素追加ロジック( array_splice($form, $pos,0, $new_ele ) )が要注意です。PHPのarray_splice関数が要素を追加する際に、追加された要素のキーは「0」となります。ここで要素の固有キー('last name')をつけないと、フォーム保存時にこの要素の入力した値を取得するキーが合わなくて困ります。実際に以下のようなロジックで要素を追加した方が良いでしょう
$pos = array_search('name',array_keys($form)) +1 ;
$first_arr = array_splice($form, 0, $pos ) ;
$form = array_merge( $first_arr, $new_ele, $form ) ;