Я пытаюсь заставить несколько форм работать на дисплее представлений. Все формы используют AJAX, но они мешают друг другу.
Одной из форм является форма массовых операций представлений, которая превращает таблицу представлений в форму «представления». Вторая форма — это форма «быстрого редактирования», доступная для каждой строки в представлении. Проблема в том, что когда я отправляю любую из форм из быстрого редактирования, он также пытается отправить форму «viewsForm» (чего делать не следует), что приводит к ошибкам проверки в этой форме. Он также не принимает мой обратный вызов ajax для моей пользовательской формы, о чем свидетельствует «обратный вызов ajax пуст или не может быть вызван» в dblog.
Если я отключу массовые операции просмотра, это будет работать так, как задумано, но с несколькими формами на странице я не могу понять, как сообщить кнопке «Отправить», которую я использую, только для отправки формы, принадлежащей кнопке отправки.
Я предоставил свой класс построителя формы для справки
<?php
пространство имен Drupal\request_system\Form;
используйте Drupal\Core\Form\FormBase;
используйте Drupal\Core\Form\FormStateInterface;
используйте Drupal\Core\Ajax\AjaxResponse;
используйте Drupal\Core\Ajax\ReplaceCommand;
используйте Drupal\Core\Ajax\HightlightCommand;
/**
* Обеспечивает форму запроса системы.
*/
класс QuickEditForm расширяет FormBase {
публичный $sub_id = 0;
публичный $entity_id = 0;
/**
* {@inheritdoc}
*/
публичная функция getFormId() {
вернуть 'request_system_quick_edit-'. $это->sub_id;
}
/**
* {@inheritdoc}
*/
общедоступная функция buildForm (массив $ form, FormStateInterface $ form_state) {
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($this->entity_id);
$опции = [];
$options['_none'] = '- Выберите один -';
если ($entity->bundle() == 'book_request') {
$statuses = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([
'vid' => 'book_request_status',
]);
}
// Показывать только "доступно у поставщика" и "ожидание"
foreach ($статусы как $статус) {
if ($status->getName() == 'В ожидании' || $status->getName() == 'Доступно от поставщика') {
$options[$status->id()] = $status->getName();
}
если ($status->id() == $entity->field_request_status->getString()) {
$options[$status->id()] = $status->getName();
}
}
$form['quick_edit'] = [
'#type' => 'контейнер',
'#id' => 'быстрое редактирование-обертка-'. $это->sub_id,
];
$form['quick_edit']['статус'] = [
'#тип' => 'набор полей',
'#title' => 'Обновления статуса',
'#name' => 'обёртка-обновления',
];
if (!$entity->field_aph_shipment_number->isEmpty() || !$entity->field_library_shipment_number->isEmpty()) {
$form['quick_edit']['статус']['значение'] = [
'#type' => 'предмет',
'#title' => 'Статус запроса: ',
'#markup' => \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($entity->field_request_status->getString())->getName(),
];
// Показать сообщение о том, что товар является частью поставки
$form['quick_edit']['status']['shipment_number'] = [
'#markup' => 'Этот запрос является частью доставки.',
];
}
еще {
// Отключите это поле, если статус запроса не «Ожидание» или «Доступно у поставщика», или если товар относится к отгрузке
$form['quick_edit']['статус']['значение'] = [
'#тип' => 'выбрать',
'#title' => 'Статус',
'#options' => $options,
'#default_value' => $entity->field_request_status->getString(),
];
if ($entity->field_request_status->getString() != \Drupal\request_system\Controller\RequestSystemController::getStatus('Pending') && $entity->field_request_status->getString() != \Drupal\request_system\Controller\ RequestSystemController::getStatus('Доступно у поставщика')) {
$form['quick_edit']['status']['value']['#disabled'] = TRUE;
}
}
$form['quick_edit']['статус']['сообщение'] = [
'#тип' => 'текстовое поле',
'#title' => $this->t('Сообщение'),
];
$form['quick_edit']['status']['notify_user'] = [
'#type' => 'флажок',
'#title' => 'Уведомить заемщика',
];
// Разрешить редактирование каталога APH #
$form['quick_edit']['другое'] = [
'#тип' => 'набор полей',
'#title' => 'Другое',
'#name' => 'другая-обертка',
];
$form['quick_edit']['other']['aph_catalog_number'] = [
'#тип' => 'текстовое поле',
'#title' => 'Каталог APH №',
'#default_value' => $entity->field_attached_copy_aph_number->getString(),
'#description' => $entity->field_attached_copy_main_record->isEmpty() ? '' : 'Невозможно изменить каталожный номер APH при назначении основной записи.',
'#disabled' => $entity->field_attached_copy_main_record->isEmpty() ? ЛОЖЬ ПРАВДА,
];
$form['quick_edit']['id'] = [
'#type' => 'скрытый',
'#value' => $this->entity_id,
];
$form['quick_edit']['actions'] = [
'#type' => 'действия',
];
$form['quick_edit']['actions']['submit'] = [
'#type' => 'отправить',
'#value' => $this->t('Сохранить'),
'#ajax' => [
'обратный вызов' => '::quickEditAjax',
'обертка' => 'быстрое редактирование-обертка-'. $это->sub_id,
],
'#validate' => '::validate',
'#limit_validation_errors' => [['id'],['status']],
'#submit' => ['::quickEditAjaxSubmit'],
];
// $form['quick_edit']['actions']['cancel'] = [
// '#type' => 'отправить',
// '#value' => 'Отмена',
// ];
вернуть $ форму;
}
/**
* {@inheritdoc}
*/
общедоступная функция validateForm (массив и $ форма, FormStateInterface $ form_state) {
$values = $form_state->getValues();
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($values['id']);
if ($values['status'] == \Drupal\request_system\Controller\RequestSystemController::getStatus("Отправлено из библиотеки займов")) {
если (счетчик($entity->field_imcid->referencedEntities()) == 0) {
$form_state->setErrorByName('status','Невозможно пометить этот элемент как отправленный, так как элемент библиотеки не прикреплен.');
}
}
}
/**
* {@inheritdoc}
*/
публичная функция submitForm (массив и $ форма, FormStateInterface $ form_state) {
}
публичная функция quickEditAjax(&$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
если ($form_state->hasAnyErrors()) {
$form['status_messages'] = [
'#type' => 'status_messages',
'#вес' => -1000,
];
$form['#sorted'] = ЛОЖЬ;
}
$response = новый AjaxResponse();
$status = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($values['status']);
$response->addCommand(new ReplaceCommand('.request-status-'. $values['id'],$status->getName()));
$response->addCommand(new ReplaceCommand('#quick-edit-wrapper-'. $this->sub_id,$form));
$response->addCommand(new HightlightCommand('#row-'. $values['id']));
вернуть $ответ;
}
общедоступная функция quickEditAjaxSubmit(&$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
// Сначала загружаем сущность
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($values['id']);
$entity->set('field_request_status',$values['status']);
$сущность->сохранить();
$form_state->setRebuild();
}
}
И способ, которым я отображаю форму, - через
$form = \Drupal::classResolver()->getInstanceFromDefinition('Drupal\request_system\Form\QuickEditForm');
$form->sub_id = $entity->id();
$form->entity_id = $entity->id();
$build['form'] = \Drupal::formBuilder()->getForm($form);
Похоже, что когда представление отображается, оно объединяет все формы в один, поэтому, когда вы нажимаете «Сохранить» в подчиненной форме, оно фактически отправляет форму массовых операций представлений. Я не уверен, как это решить или заставить его прекратить это делать.
Я уже две недели ломаю голову над этим, пытаясь решить эту проблему, и не могу понять, в чем проблема.
Любая помощь будет ОЧЕНЬ оценена.
РЕДАКТИРОВАТЬ: я приложил скриншот того, чего мы пытаемся достичь. Флажок слева — это массовая операция просмотра, форма «быстрое редактирование» находится справа через «расширяемый столбец таблицы».