Студия разработки сайтов и приложений

Netspark.ru

Скрипт для типографики

Typofilter.js

Создание нескольких одинаковых форм на одной странице

Недавно возникла нужда написать функцию, создающую несколько одинаковых форм на одной странице. Формы небольшие, состоят из одного текстового поля и кнопки, а также (что важно) двух переменных для внутреннего использования:

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;

Комментарии