Рейтинг:1

Как отфильтровать автозаполнение для зависимого поля?

флаг km

Цель. Как отфильтровать автозаполнение на основе связанного поля? В этом домене выбирается организация, а затем автозаполнение должно позволять выбирать только элементы, созданные этой организацией.

Установка включает в себя

  • встроенная форма объекта для выбора организации. Это триггерное поле.
  • поле автозаполнения для выбора связанной облигации этой организации

Инициирующий элемент называется «эмитент». Это структура формы:

Структура формы IEF эмитента

Структура поля автозаполнения в форме:

Структура формы Deal Bond

Забывая о том, как ajax запускается, когда встроенная форма сущности завершается, это еще одна проблема. У меня есть система, в которой фальшивый/инициирующий список выбора изменяется на основе наблюдателя мутаций, запускающего ajax. Я исследовал попытку связать событие, пытаясь применить ajax к встроенному элементу формы объекта и пытаясь вызвать ajax с помощью drupal.ajax.

Как установить идентификатор значения фильтра. Я вижу 2 способа, самый чистый - передать параметр #filter в #selection_settings

$form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#selection_settings'] = [
  'target_bundles' => ['бин'],
  'filter' => ['field_bond_issuer' => $issuer_id],
];

Я вижу значение, установленное в элементе #prefix в форме после запуска ajax.

$form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#prefix'] = 'тестирование добавления контента: идентификатор эмитента' . $эмитент_id;
return $form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond'];

Внешний вид поля:

введите описание изображения здесь

HTML

<input data-drupal-selector="edit-field-para-deal-information-0-subform-field-deal-reference-bond-0-target-id" aria-describedby="edit-field-para-deal-information-0-subform-field-deal-reference-bond-0-target-id--_drZ4Yf-StI--description" class="form-autocomplete form-text ui-autocomplete-input" data-autocomplete-path="/entity_reference_autocomplete/node/default%3Anode_by_issuer/tT7cuAtHgjMlRrK6OypcvFEJNTvFEDSmFImi6iBhNNw" type="text" id="edit-field-para-deal-information-0-subform-field-deal-reference-bond-0-target-id--_drZ4Yf-StI" name="field_para_deal_information[0][subform][field_deal_reference_bond][0][target_id]" value="" size="60" maxlength="1024" placeholder="" autocomplete="off">

Показывает, что default:node_by_issuer установлен в функции ajax (полный):

function cbi_deal_id_handle_ajax (массив и $ форма, FormStateInterface $ form_state) {
  $issuer_para_field = $form_state->getValue('field_para_issuer_information');
  $issuer_field = $issuer_para_field[0]['subform']['field_bond_issuer'];
  $issuer_field_value = $issuer_field['target_id'];
  $issuer_id = взорвать(':', $issuer_field_value)[1];


  $form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#selection_handler'] = 'default:node_by_issuer';
  $form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#selection_settings'] = [
'target_bundles' => ['бин'],
'filter' => ['field_bond_issuer' => $issuer_id],
  ];

 $form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#prefix'] = 'тестирование добавления контента: идентификатор эмитента' . $эмитент_id;
 return $form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond'];
 }

Я ломаю обзор в /web/core/lib/Drupal/Core/Render/Element/FormElement.php строку 187 и подтвердите, что переменная фильтра не установлена.

Похоже, что поле автозаполнения не обновляется настройками, относящимися к функции автозаполнения. Если я установлю ajax для обновления формы с помощью

['#selection_handler'] = 'по умолчанию: node_by_tester';

нет никаких изменений в обработчике в основном рендерере. Значение, установленное при изменении исходной формы, остается (node_by_issuer).

Изменение формы ajax с оберткой div, чтобы проверить, имеет ли какое-либо значение идентификатор оболочки формы с хэш-кодом на конце.

function cbi_deal_id_field_widget_entity_reference_paragraphs_form_alter(&$element, &$form_state, $context) {
  if ($element['#paragraph_type'] == 'deal_information') {
    $items = $context['items'];
    $bond = $items->getParent()->getEntity();
    $element['subform']['field_deal_reference_bond']['widget'][0]['target_id']['#selection_handler'] = 'default:node_by_issuer';
    $element['subform']['field_deal_reference_bond']['#prefix'] = '<div id="test-wrapper">';
    $element['subform']['field_deal_reference_bond']['#suffix'] = '</div>';

    $element['subform']['ajax_trigger_button'] = [
      '#тип' => 'выбрать',
      '#ajax' => [
        'обратный вызов' => 'cbi_deal_id_handle_ajax',
        'событие' => 'размытие',
        'обертка' => 'тест-обертка',
        'прогресс' => [
          'тип' => 'пульсирующий',
          'message' => t('Загружаются сведения об эмитенте...'),
         ],
      ],
     '#варианты' => [
      '1' => т('Один'),
      '2' => т('Два'),
      '3' => т('Три'),
     ],
   ];

  если ($bond->isNew()) {
    возвращаться;
  }
...

Чтобы фильтровать данные, я создал плагин в соответствии с https://fivejars.com/blog/when-drupal-best-choice-your-website. Я ожидаю, что selection_handler свойство обращается к нему. Это вызывается без доступа к данным фильтра:

<?php

пространство имен Drupal\cbi_deal_id\Plugin\EntityReferenceSelection;

используйте Drupal\node\Plugin\EntityReferenceSelection\NodeSelection;

/**
 * Обеспечивает определенный контроль доступа для типа сущности узла.
 *
 * @EntityReferenceSelection(
 * id = "по умолчанию: node_by_issuer",
 * label = @Translation("Узел по выбору поля"),
 * entity_types = {"узел"},
 * группа = "по умолчанию",
 * вес = 3
 * )
 */
класс BondByIssuerSelection расширяет NodeSelection {

 /**
  * {@inheritdoc}
  */
 защищенная функция buildEntityQuery ($ match = NULL, $ match_operator = 'CONTAINS') {
   \Drupal::logger('cbi_deal_id')->notice('загрузка запроса объекта сборки с помощью');
   $query = parent::buildEntityQuery($match, $match_operator);
   $handler_settings = $this->configuration['handler_settings'];
   если (!isset($handler_settings['фильтр'])) {
     вернуть $запрос;
   }
   $filter_settings = $handler_settings['фильтр'];
   foreach ($filter_settings как $field_name => $value) {
     $query->условие($field_name, $value, '=');
   }
   вернуть $запрос;
 }

}

Ajax возвращает весь абзац

Отрегулируйте ajax, чтобы заменить весь абзац, как было предложено.

$form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['target_id']['#selection_settings'] = 
  [
     'target_bundles' => ['связь'],
     'фильтр' => ['field_issuer_filter' => 4993],
   ];
$form['field_para_deal_information']['widget'][0]['subform']['field_deal_reference_bond']['#prefix'] = 'тестирование добавления контента: идентификатор эмитента' . $эмитент_id;
  возврат $form['field_para_deal_information'];
}

В файле соответствия /src/Entity/CbiDealIdEntityAutocompleteMatcher.php

Настройки фильтра находятся в контроллере сопоставления автозаполнения, но не в обновленных значениях.

введите описание изображения здесь

Заключение

Я попытался создать контроллер https://www.chapterthree.com/blog/how-alter-entity-autocomplete-results-drupal-8. Он вызывается, но у меня нет данных фильтра, и я не вижу, как обратиться к $form_state, чтобы получить идентификатор из встроенной формы сущности.

Второй способ адресации запроса — через настраиваемый маршрут. Возможно может изменить маршрут от ajax. Требуется расследование.

Каков самый простой метод фильтрации по значению в поле встроенной сущности?

No Sssweat avatar
флаг ua
В обратном вызове ajax вам нужно просто вернуть $form['field_para_deal_information'];`

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

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