Ajax и hook_form_alter

Я получаю сообщение об ошибке « Выбранное вами значение не является допустимым выбором » для измененного поля Ajax, когда я отправляю пользовательскую измененную форму узла/добавления. В журнал также записывается ошибка «Недопустимый выбор». Это версия приложения для Drupal 9, которое я разработал с использованием Drupal 7, которое работало. Функциональность Ajax работает. Почему? Как это исправить?

Я считаю, что ошибка исходит из некоторого кода Symfony. Я динамически изменяю два элемента формы "выбрать". С первым вроде проблем нет. Я делаю то же самое для обоих элементов формы.

          function bncreports_form_node_bnc_message_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
  $form['actions']['submit']['#submit'][]  = 'bncreports_node_bnc_message_form_submit';
  $form['#title'] = t('Create Contact Us');

  $user = User::load(\Drupal::currentUser()->id());
  $district_id = $user->get('field_district')->value;

  $form['field_first_name']['widget'][0]['value']['#default_value'] = $user->get('field_first_name')->value;
  $form['field_last_name']['widget'][0]['value']['#default_value'] = $user->get('field_last_name')->value;
  $form['field_email']['widget'][0]['value']['#default_value'] = $user->getEmail();
  $form['field_email']['widget'][0]['value']['#attributes'] = ['onblur' => 'this.value=this.value.toLowerCase();'];
  $form['field_phone']['widget'][0]['value']['#default_value'] = $user->get('field_phone')->value;
  $form['field_district']['widget'][0]['value']['#default_value'] = $district_id;
  if (isset($form['field_district']['widget']['#default_value']))
    $form['field_district']['widget']['#default_value'] = $district_id; // wtf?

  if ($user->hasRole('administrator') || $user->hasRole('bnc_operator') || $user->hasRole('ao_user')) {
    $form['field_office']['#access'] = false;
    $form['field_office_name']['#access'] = false;
    $form['field_office_names']['#access'] = false;
    $form['field_site_codes']['#access'] = false;
    $form['field_district']['widget']['#ajax'] = [
      'event' => 'change',
      'callback' => 'bncreports_ajax_offices_and_user',
      'wrapper' => ['ajax-wrapper-field-offices', 'ajax-wrapper-field-user'],
    ];
    $form['field_offices']['#prefix'] = '<div id="ajax-wrapper-field-offices">';
    $form['field_offices']['#suffix'] = '</div>';
    $form['field_user']['#prefix'] = '<div id="ajax-wrapper-field-user">';
    $form['field_user']['#suffix'] = '</div>';

    $district_id = $form_state->hasValue('field_district')
      ? $form_state->getValue('field_district')[0]['value']
      : false;

    $form['field_offices']['widget']['#options'] = $district_id
      ? Functions::officeNames($district_id)
      : [];

    $form['field_user']['widget']['#options'] = $district_id
      ? ['_none' => '- Select a value -'] + Functions::districtUserLastandFirstNames($district_id)
      : ['_none' => '- Select a value -'];
  } else { // Alterations for court users only
    $form['bnc_prefix']['#markup'] =
      '<p>BNC User Support: ' . Constants::BNC_PHONE_NO
      . ' <a href="mailto:' . Constants::BNC_EMAIL . '">' . Constants::BNC_EMAIL . '</a></p>'
      . '<p><a href="' . Constants::AO_CONTACTS_URL . '">AO Program and CM/ECF Contacts</a></p>'
      . '<h4>Unable to find what you need? Send us a message.</h4>';
    $form['bnc_prefix']['#weight'] = -1;

    $form['field_offices']['#access'] = false;
    $form['field_office_name']['#access'] = false;
    $form['field_office_names']['#access'] = false;
    $form['field_site_codes']['#access'] = false;
    $form['field_user']['#access'] = false;
    $form['field_non_user_name']['#access'] = false;
    $form['field_non_user_phone']['#access'] = false;
    $form['field_assigned_to']['#access'] = false;
    $form['revision_information']['#access'] = false;

    $office = $user->get('field_office')->value;
    $form['field_district']['widget']['#default_value'] = $district_id;
    $form['field_office']['widget']['#options'] = Functions::officeNames($district_id);
    $form['field_office']['widget']['#default_value'] = $office;
    $form['field_office_name']['widget'][0]['value']['#default_value'] = Functions::officeName($district_id, $office);

    $form['#attached']['library'][] = 'bncreports/restricted_contact_log';
  }
}

    function bncreports_ajax_offices_and_user(array $form, FormStateInterface $form_state): AjaxResponse
{
  $response = new AjaxResponse();
  // Issue a command that replaces the elements 'field_offices' and 'field_user'

  $response->addCommand(new ReplaceCommand('#ajax-wrapper-field-office', $form['field_offices']));
  $response->addCommand(new ReplaceCommand('#ajax-wrapper-field-user', $form['field_user']));

  return $response;
}

1 ответ

Проблема в том, что для списка field_user нет разрешенных значений. Решение состоит в том, чтобы использовать обратный вызов функции разрешенных значений. Это делается в синхронизации конфигурации для полевого хранилища. Установите допустимое свойство функции значения и импортируйте. Необходимо предоставить uuid для переопределения существующей конфигурации.

В моем hook_form_alter:

      $_SESSION['selected_district_id'] = $district_id;

В моем xxx.module:

      function bncreports_allowed_values_function(FieldStorageConfig $definition, ContentEntityInterface $entity = NULL, $cacheable): array
{
  // NOTE: This is defined in Configuation synchronization for Field Storage (see node.field_user)
  if ($entity->bundle() == 'bnc_message') { // Add a custom field_user options for BNC Message nodes.
    $district_id = $_SESSION['selected_district_id'] ?? null;
    return Functions::districtUserLastandFirstNames($district_id);
  }

  throw new Exception("Allowed values function for {$entity->bundle()} is not allowed.");
}
Другие вопросы по тегам