Для чего используется $ form_state?

33

Для чего $form_stateобычно используется API-интерфейс Form, если он используется в качестве аргумента?

В частности, я ищу пример, когда он используется.

chrisjlee
источник

Ответы:

48

$form_stateявляется одним из аргументов, передаваемых обработчику отправки формы или обработчику проверки формы; его основное использование - получение значений, введенных пользователем в форме (см. содержимое $form_state['values']), но оно содержит другие значения, которые можно использовать для других целей.
Документация для drupal_build_form () содержит список других значений, содержащихся в этом массиве, в том числе следующие:

  • перестроение: обычно после завершения всей обработки формы и запуска обработчиков отправки считается, что форма выполнена, и drupal_redirect_form () перенаправит пользователя на новую страницу с помощью запроса GET (поэтому обновление браузера не отправляет повторно форма). Однако, если для 'rebuild' было установлено значение TRUE, новая копия формы немедленно создается и отправляется в браузер, а не перенаправляется. Это используется для многоэтапных форм, таких как мастера и формы подтверждения. Обычно $form_state['rebuild']устанавливается обработчиком отправки, поскольку обычно внутри обработчика отправки определяется логика, определяющая, выполняется ли форма или требуется другой шаг. Однако обработчик проверки может уже установить так, $form_state['rebuild']чтобы обработка формы обходила обработчики отправки и вместо этого перестраивала форму, даже если ошибок проверки нет.
  • redirect: используется для перенаправления формы при отправке. Это может быть либо строка, содержащая целевой URL, либо массив аргументов, совместимых с drupal_goto(). Смотрите drupal_redirect_form()для полной информации.
  • кеш: при установке TRUEна исходную, необработанная структура формы будет кэшироваться, что позволяет перестраивать всю форму из кеша. Типичный рабочий процесс формы включает два запроса страницы; сначала создается и обрабатывается форма для заполнения пользователем. Затем пользователь заполняет форму и отправляет ее, вызывая запрос второй страницы, в котором форма должна быть построена и обработана. По умолчанию $formи $form_stateстроятся с нуля во время каждого из этих запросов страниц. Часто это необходимо или желательно , чтобы сохраняться $formи $form_stateпеременные из запроса начальной страницы на тот , который обрабатывает представление. 'cache' может быть установлен в TRUE, чтобы сделать это. Ярким примером является форма с поддержкой Ajax, в которойajax_process_form()включает кэширование форм для всех форм, которые содержат элемент со свойством #ajax. (У обработчика Ajax нет способа построить саму форму, поэтому он должен полагаться на кэшированную версию.) Обратите внимание, что сохранение $formи $form_stateпроисходит автоматически для (многошаговых) форм, имеющих установленный флаг 'rebuild', независимо от значения для «кэш».
  • хранилище: $form_state['storage']не является специальным ключом, и в API-интерфейсе формы для него не предоставляется никакой конкретной поддержки. По традиции это было место, где данные конкретного приложения хранились для связи между функциями отправки, проверки и построения форм, особенно в многоэтапной форме. Реализации формы могут использовать любой ключ (ключи) внутри $form_state(кроме ключей, перечисленных здесь и других зарезервированных ключей, используемых внутренними компонентами API формы) для этого типа хранилища. Рекомендуемый способ убедиться, что выбранный ключ не конфликтует с теми, которые используются API-интерфейсом формы или другими модулями, - это использовать имя модуля в качестве имени ключа или префикс для имени ключа. Например, модуль Node использует$form_state['node'] в формах редактирования узла для хранения информации об редактируемом узле, и эта информация остается доступной при последовательных нажатиях кнопки «Предварительный просмотр», а также при окончательном нажатии кнопки «Сохранить».

Другими функциями, которые получают в $form_stateкачестве аргумента, являются hook_form_alter () и hook_form_FORM_ID_alter () .

В качестве примера кода, использующего этот аргумент, вы можете посмотреть на comment_form_submit () , который содержит следующий код:

function comment_form_submit($form, &$form_state) {
  $node = node_load($form_state['values']['nid']);
  $comment = comment_form_submit_build_comment($form, $form_state);
  if (user_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_NODE_OPEN)) {
    // Save the anonymous user information to a cookie for reuse.
    if (user_is_anonymous()) {
      user_cookie_save(array_intersect_key($form_state['values'], array_flip(array('name', 'mail', 'homepage'))));
    }

    comment_save($comment);
    $form_state['values']['cid'] = $comment->cid;

    // Add an entry to the watchdog log.
    watchdog('content', 'Comment posted: %subject.', array('%subject' => $comment->subject), WATCHDOG_NOTICE, l(t('view'), 'comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid)));

    // Explain the approval queue if necessary.
    if ($comment->status == COMMENT_NOT_PUBLISHED) {
      if (!user_access('administer comments')) {
        drupal_set_message(t('Your comment has been queued for review by site administrators and will be published after approval.'));
      }
    }
    else {
      drupal_set_message(t('Your comment has been posted.'));
    }
    $query = array();
    // Find the current display page for this comment.
    $page = comment_get_display_page($comment->cid, $node->type);
    if ($page > 0) {
      $query['page'] = $page;
    }
    // Redirect to the newly posted comment.
    $redirect = array('node/' . $node->nid, array(
        'query' => $query,
        'fragment' => 'comment-' . $comment->cid,
      ));
  }
  else {
    watchdog('content', 'Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject), WATCHDOG_WARNING);
    drupal_set_message(t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject)), 'error');
    // Redirect the user to the node they are commenting on.
    $redirect = 'node/' . $node->nid;
  }
  $form_state['redirect'] = $redirect;
  // Clear the block and page caches so that anonymous users see the comment
  // they have posted.
  cache_clear_all();
}

Чтобы понять, что $form_state['values']содержится, вам нужно взглянуть на значения, добавленные $formв comment_form () . Например, $form_stateсодержит, $form_state['values']['name']потому что $formсодержит $form['author']['name']. Вообще, если $form['field']есть поле формы, то $form_stateбудет содержать $form_state['values']['field'].

киамалуно
источник
Если мы хотим изменить значения формы или отключить многозначные кнопки полей с помощью hook_form_alter, какую переменную следует изменить $ form или $ from_state? (При реализации с использованием AJAX или без AJAX). $ Form_state специально используется для ajax?
kiranking
1
@kiranking Обычно обратный вызов AJAX возвращает часть $formмассива; это конструктор форм, который проверяет содержимое $form_state. Это то, что я видел во всех обратных вызовах AJAX, реализованных модулями, которые делают правильные вещи.
kiamlaluno