简体   繁体   English

Ajax 和 hook_form_alter

[英]Ajax and hook_form_alter

I'm getting a " The value you selected is not a valid choice. " error for an Ajax modified field when I submit a custom altered node/add form.当我提交自定义更改节点/添加表单时,我收到“您选择的值不是有效选择。 ” Ajax 修改字段错误。 An "Illegal choice error is also written to the log. This a Drupal 9 version of an app that I developed using Drupal 7 which worked. The Ajax functionality is working. Why? How do I fix it? “非法选择错误也被写入日志。这是我使用 Drupal 7 开发的应用程序的 Drupal 9 版本,它工作。Ajax 功能正在工作。为什么?我该如何修复它?

I believe the error is coming from some Symfony code.我相信错误来自一些 Symfony 代码。 I'm dynamically modifying two "select" form elements.我正在动态修改两个“选择”表单元素。 The first doesn't appear to have the problem.第一个似乎没有问题。 I'm doing the same thing for both form elements.我对两个表单元素都做同样的事情。

    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;
}

Problem is there are no allowed values for the field_user list.问题是 field_user 列表没有允许的值。 Solution is to use an allowed values function callback.解决方案是使用允许值函数回调。 This is done in Configuration synchronization for Field Storage.这是在 Field Storage 的配置同步中完成的。 Set the allowed value function property and import.设置允许的值函数属性并导入。 Need to provide uuid to override existing config.需要提供 uuid 来覆盖现有配置。

In my hook_form_alter:在我的 hook_form_alter 中:

$_SESSION['selected_district_id'] = $district_id;

In my xxx.module:在我的 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.");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM