Încerc să fac mai multe forme să funcționeze într-un afișaj de vizualizări. Toate formularele folosesc AJAX, dar par să interfereze unele cu altele.
Un formular este formularul Views Bulk Operations care transformă tabelul de vizualizări într-un „viewsForm”. Al doilea formular este un formular de „editare rapidă” disponibil pe fiecare rând din vizualizare. Problema este că atunci când trimit oricare dintre formularele din editarea rapidă, încearcă să trimită și formularul „viewsForm” (ceea ce nu ar trebui să facă), rezultând erori de validare pe formularul respectiv. De asemenea, nu preia apelul meu ajax pentru formularul meu personalizat, așa cum arată „callbackul ajax este gol sau nu poate fi apelat” din dblog.
Dacă dezactivez operațiunile de vizualizare în bloc, acest lucru funcționează conform intenției, dar cu mai multe formulare pe pagină, nu îmi pot da seama cum să spun butonului „trimitere” pe care îl folosesc pentru a trimite doar formularul care aparține butonului de trimitere.
Am furnizat clasa mea de constructor de forme pentru referință
<?php
spațiu de nume Drupal\sistem_cerere\Form;
utilizați Drupal\Core\Form\FormBase;
utilizați Drupal\Core\Form\FormStateInterface;
utilizați Drupal\Core\Ajax\AjaxResponse;
utilizați Drupal\Core\Ajax\ReplaceCommand;
utilizați Drupal\Core\Ajax\HightlightCommand;
/**
* Oferă un formular de cerere de sistem.
*/
clasa QuickEditForm extinde FormBase {
public $sub_id = 0;
public $entity_id = 0;
/**
* {@inheritdoc}
*/
funcția publică getFormId() {
returnează „request_system_quick_edit-” . $this->sub_id;
}
/**
* {@inheritdoc}
*/
funcția publică buildForm(array $form, FormStateInterface $form_state) {
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($this->entity_id);
$opțiuni = [];
$options['_none'] = '- Selectați una -';
dacă ($entity->bundle() == 'book_request') {
$status = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([
'vid' => 'book_request_status',
]);
}
// Afișează numai „disponibil de la furnizor” și „În așteptare”
foreach ($status ca $status) {
if ($status->getName() == „În așteptare” || $status->getName() == „Disponibil de la furnizor”) {
$options[$status->id()] = $status->getName();
}
if ($status->id() == $entity->field_request_status->getString()) {
$options[$status->id()] = $status->getName();
}
}
$form['quick_edit'] = [
'#type' => 'container',
'#id' => 'Quick-edit-wrapper-'. $this->sub_id,
];
$form['quick_edit']['status'] = [
'#type' => 'fieldset',
'#title' => 'Actualizări de stare',
'#name' => 'update-wrapper',
];
dacă (!$entity->field_aph_shipment_number->isEmpty() || !$entity->field_library_shipment_number->isEmpty()) {
$form['quick_edit']['status']['value'] = [
'#type' => 'articol',
'#title' => 'Starea solicitării: ',
'#markup' => \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($entity->field_request_status->getString())->getName(),
];
// Afișează mesajul care indică că articolul face parte dintr-o expediție
$form['quick_edit']['status']['shipment_number'] = [
'#markup' => 'Această solicitare face parte dintr-o expediere.',
];
}
else {
// Dezactivează acest câmp dacă starea cererii nu este „În așteptare” sau „Disponibil de la furnizor” sau dacă articolul aparține unei expedieri
$form['quick_edit']['status']['value'] = [
'#type' => 'selectați',
'#title' => 'Stare',
'#options' => $opțiuni,
'#default_value' => $entity->field_request_status->getString(),
];
if ($entity->field_request_status->getString() != \Drupal\request_system\Controller\RequestSystemController::getStatus('În așteptare') && $entity->field_request_status->getString() != \Drupal\request_system\Controller\ RequestSystemController::getStatus('Disponibil de la furnizor')) {
$form['quick_edit']['status']['value']['#disabled'] = TRUE;
}
}
$form['quick_edit']['status']['mesaj'] = [
'#type' => 'textarea',
'#title' => $this->t('Mesaj'),
];
$form['quick_edit']['status']['notify_user'] = [
'#type' => 'caseta de selectare',
'#title' => 'Anunțați împrumutatul',
];
// Permite editarea catalogului APH #
$form['quick_edit']['other'] = [
'#type' => 'fieldset',
'#title' => 'Altele',
'#name' => 'alt-wrapper',
];
$form['quick_edit']['other']['aph_catalog_number'] = [
'#type' => 'câmp text',
'#title' => 'Număr de catalog APH',
'#default_value' => $entity->field_attached_copy_aph_number->getString(),
'#description' => $entity->field_attached_copy_main_record->isEmpty() ? '' : 'Nu se poate schimba numărul de catalog APH atunci când este atribuită o înregistrare principală.',
'#disabled' => $entity->field_attached_copy_main_record->isEmpty() ? FALS ADEVARAT,
];
$form['quick_edit']['id'] = [
'#type' => 'ascuns',
'#value' => $this->entity_id,
];
$form['quick_edit']['actions'] = [
'#type' => 'acțiuni',
];
$form['quick_edit']['actions']['submit'] = [
'#type' => 'trimite',
'#value' => $this->t('Salvare'),
'#ajax' => [
'callback' => '::quickEditAjax',
'wrapper' => 'quick-edit-wrapper-'. $this->sub_id,
],
'#validate' => '::validate',
'#limit_validation_errors' => [['id'],['status']],
'#submit' => ['::quickEditAjaxSubmit'],
];
// $form['quick_edit']['actions']['cancel'] = [
// '#type' => 'trimite',
// '#value' => 'Anulează',
// ];
returnează $form;
}
/**
* {@inheritdoc}
*/
funcția publică validateForm(matrice &$form, FormStateInterface $form_state) {
$valori = $form_state->getValues();
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($values['id']);
if ($values['status'] == \Drupal\request_system\Controller\RequestSystemController::getStatus(„Livrat din biblioteca de împrumut”)) {
if (count($entity->field_imcid->referencedEntities()) == 0) {
$form_state->setErrorByName('status','Nu se poate marca acest articol livrat deoarece nu este atașat niciun articol din bibliotecă.');
}
}
}
/**
* {@inheritdoc}
*/
funcția publică submitForm(matrice &$form, FormStateInterface $form_state) {
}
funcția publică quickEditAjax(&$form, FormStateInterface $form_state) {
$valori = $form_state->getValues();
dacă ($form_state->hasAnyErrors()) {
$form['status_messages'] = [
'#type' => 'status_messages',
'#weight' => -1000,
];
$form['#sorted'] = FALS;
}
$răspuns = AjaxResponse nou();
$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']));
returnează $răspuns;
}
funcția publică quickEditAjaxSubmit(&$form, FormStateInterface $form_state) {
$valori = $form_state->getValues();
// Încărcați mai întâi entitatea
$entity = \Drupal::entityTypeManager()->getStorage('lms_request')->load($values['id']);
$entity->set('field_request_status',$values['status']);
$entity->salvare();
$form_state->setRebuild();
}
}
Și modul în care redau formularul este via
$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);
Se pare că atunci când vizualizarea este redată, combină toate formularele într-un singur , așa că atunci când dați clic pe „Salvați” pe subformular, de fapt trimite formularul de operațiuni în bloc de vizualizări. Nu sunt sigur cum să rezolv acest lucru sau să o fac să nu mai facă asta.
Mă bat cu capul în asta timp de două săptămâni încercând să rezolv asta și nu pot să-mi dau seama care este problema.
Orice ajutor ar fi foarte apreciat.
EDIT: Am atașat o captură de ecran a ceea ce încercăm să realizăm. Caseta de selectare din stânga este vizualizarea operațiunii în bloc, formularul „editare rapidă” este în extrema dreaptă prin „coloana tabel extensibil”