Рейтинг:0

FormAPI - значения полей, добавленных AJAX, отсутствуют в массиве значений при отправке

флаг vn

Я использую Form API для создания формы, в которой у меня есть несколько экземпляров набора полей. Каждый набор полей содержит одни и те же поля, одно для хранения адреса электронной почты, а другое для другого бита информации. Но по сути они оба текстовые поля, которые используют автозаполнение, которое отлично работает. Но у меня возникла проблема в обработчике отправки, описанном ниже в моем коде.

$form['authors_container']['authors_fieldset'][$i] = [
    '#тип' => 'набор полей',
    '#атрибуты' => [
      'класс' => ['автор-полесет']
    ],
    'электронная почта' => [
      '#тип' => 'текстовое поле',
      '#title' => 'Электронная почта автора',
      '#значение' => $emailValue,
      '#autocomplete_route_name' => 'discussion_papers.contact_email_lookup',
      '#атрибуты' => [
        'класс' => ['автор-электронная почта']
      ]
    ],
    'принадлежность' => [
      '#тип' => 'текстовое поле',
      '#title' => 'Принадлежность',
      '#value' => $affiliationValue,
      '#атрибуты' => [
        'класс' => ['принадлежность автора']
      ]
    ]
  ];

Затем у меня есть кнопка AJAX для добавления дополнительных экземпляров вышеуказанного набора полей с соответствующим обработчиком:

$form['authors_container']['add_author'] = [
  '#type' => 'отправить',
  '#value' => 'Добавить другого автора',
  '#submit' => ['::AddAuthor'],
  '#limit_validation_errors' => [],
  '#ajax' => [
    'обратный вызов' => '::getAuthorsFields',
    'wrapper' => 'контейнер авторов',
    'метод' => 'заменить',
    'отключить-перефокусировку' => правда,
  ]
];

общедоступная функция addAuthor($form, FormStateInterface &$form_state) {

    $storage = $form_state->getStorage();

    если (пусто ($ хранилище ['numOfAuthors'])) 
        $storage['numOfAuthors'] = 1;

    $storage['numOfAuthors']++;
    $form_state->setStorage($storage);

    $form_state->setLimitValidationErrors([]);
    $form_state->setRebuild();
}

Все это прекрасно работает, я могу добавить столько экземпляров набора полей, сколько мне нужно.Моя проблема в том, что когда я отправляю форму, значения только самого последнего набора полей всегда пусты в $form_state['значения'] массив, но я вижу значения в $form_state['ввод'] множество. Я понимаю, что входной массив является необработанным, непроверенным вводом и что массив значений проверен, поэтому мой вопрос: почему только последний набор текстовых полей не проверен? Мой обработчик проверки не удаляет никаких значений.

Рейтинг:0
флаг de

Две возможности:

  1. Вы добавили дополнительные поля в функцию обратного вызова #ajax. Поскольку вы не показали, в какой функции были определены ваши поля, этого нельзя увидеть из вашего кода. Drupal кэширует форму при ее создании, а затем, когда форма отправляется, он удаляет все значения, не являющиеся частью исходного определения формы, в целях безопасности. Проблема с добавлением полей в функцию обратного вызова #ajax заключается в том, что форма кэшируется до функции обратного вызова, и поэтому Drupal отбрасывает отправленные значения полей.

  2. Если объявления элементов формы фактически находятся в функции построителя форм, а не являются частью функции обратного вызова #ajax, вам, вероятно, потребуется добавить #дерево в набор полей, чтобы создать массив значений:

    $form['authors_container']['authors_fieldset'][$i] = [
      '#дерево' => ИСТИНА,
      '#тип' => 'набор полей',
      ...
    

    Это сохранит каждое из отправленных значений в отдельный элемент массива значений.

AlbionBrown avatar
флаг vn
Спасибо за ответ, я постараюсь отредактировать свой вопрос, чтобы включить больше кода. Дополнительные поля добавляются только в методе buildForm, обратный вызов AJAX только увеличивает число, которое должно отображаться, а затем при перестроении формы добавляется столько, сколько хранится в хранилище состояния формы. Я пытался добавить ключ дерева, а также отключить кеш, но это не помогло. Ключ дерева также используется в родительском контейнере наборов полей. Я думаю, мне нужно отладить прямо с начала запроса на отправку, чтобы выяснить, почему Drupal их удаляет.
Jaypan avatar
флаг de
Если вы меняете значения в состоянии формы в обратном вызове ajax, они теряются. Состояние формы уже было кэшировано до обратного вызова ajax. Вам нужно будет выполнить приращение в обработчике отправки, а не в обратном вызове ajax, если вы хотите, чтобы он сохранялся. Обратные вызовы Ajax предназначены _только_ для определения того, какие элементы возвращать, а не для того, чтобы «делать» что-либо с данными.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.