Недавно возникла нужда написать функцию, создающую несколько одинаковых форм на одной странице. Формы небольшие, состоят из одного текстового поля и кнопки, а также (что важно) двух переменных для внутреннего использования:
function _my_form(&$form_state,$id1,$id2) {
$form = array();
$form['mytext'] = array(
'#type' => 'textarea',
'#title' => t("Enter text"),
'#required' => 'true',
);
$form['#id1'] = $id1;
$form['#id2'] = $id2;
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
По нажатию кнопки содержимое текстового поля записывается в БД вместе с $id1
и $id2
, которые меняются от одной формы к другой.
Сделать хотелось примерно вот что:
//...
$id2 = x;
foreach ($ids as $id1) {
$output .= drupal_get_form('_my_form',$id1,$id2);
}
//...
return $output;
Однако очевидно, что данный код работать не будет. Загвоздка в том, что все формы генерируются с одинаковым form_ID и при сохранении любой формы Друпал будет считать, что сохраняется самая первая. Поэтому $id1
и $id2
всегда будут равны указанным при создании первой формы на странице. Значит, нужно сделать, чтобы, с одной стороны, у всех форм при создании был разный ID, а с другой - чтобы создавались и обрабатывались они одной функцией.
Порывшись изрядно по Drupal.org было найдено решение в виде хука hook_forms
. Собственно, будь на странице в Drupal API правильное описание хука, искать изрядно и не пришлось бы. А так - несколько раз натыкался, и каждый раз думал, что это не выход.
Дело все в том, что в описании hook_forms
функция для Drupal 6 указана без аргументов, тогда как на деле она принимает и $form_id
, и $args
. Все сразу встало на свои места. Вот так для всех форм, начинающихся с _my_form
, задается единый конструктор:
/**
* Реализует hook_forms
*
* @param string $form_id - ID формы
* @param array $args - дополнительные параметры, полученные от drupal_get_form
* @return array
*/
function mymodule_forms($form_id,$args) {
$forms = array();
if (strpos($form_id,'_my_form') === 0) {
$forms[$form_id] = array(
'callback' => '_my_form',
'callback arguments' => $args,
);
}
return $forms;
} //function mymodule_forms
Но поскольку формы у нас стали с разными ID, Друпал при сохранении формы будет искать разные функции-обработчики. Так что нужно указать единый валидатор и обработчик при создании формы:
function _my_form(&$form_state,$id1,$id2) {
//...
//валидатор и обработчик
$form['#submit'] = array('_my_form_submit');
$form['#validate'] = array('_my_form_validate');
return $form;
}
Дело сделано. Теперь остается только немного изменить генерацию данных на странице, чтобы формы создавались с разными ID:
//...
$id2 = x;
foreach ($ids as $id1) {
//$id1, естественно, должен быть уникальным
$output .= drupal_get_form('_my_form'.$id1,$id1,$id2);
}
//...
return $output;