Commit 50defa44 authored by Christian Fritsch's avatar Christian Fritsch Committed by Merlin Axel Rutz
Browse files

Issue #2901158 by chr.fritsch, volkerk, subhojit777, Spokje: Changes are lost...

Issue #2901158 by chr.fritsch, volkerk, subhojit777, Spokje: Changes are lost when collapsing a paragraphs subform including an inline_entity_form
parent efbef0b9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -297,7 +297,7 @@ class EntityInlineForm implements InlineFormInterface {
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  protected function buildEntity(array $entity_form, ContentEntityInterface $entity, FormStateInterface $form_state) {
  public function buildEntity(array $entity_form, ContentEntityInterface $entity, FormStateInterface $form_state) {
    $form_display = $this->getFormDisplay($entity, $entity_form['#form_mode']);
    $form_display->extractFormValues($entity, $entity_form, $form_state);
    // Invoke all specified builders for copying form values to entity fields.
+17 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\inline_entity_form\Element\InlineEntityForm;
use Drupal\inline_entity_form\TranslationHelper;

/**
@@ -34,7 +35,12 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
    // WidgetSubmit will be needed once extractFormValues fills the $form_state.
    $parents = array_merge($element['#field_parents'], [$items->getName()]);
    $ief_id = $this->makeIefId($parents);

    // Get state from storage.
    $widget_state = $form_state->get(['inline_entity_form', $ief_id]);
    if (!$widget_state) {
      $form_state->set(['inline_entity_form', $ief_id], []);
    }

    $element = [
      '#type' => $this->getSetting('collapsible') ? 'details' : 'fieldset',
@@ -53,7 +59,14 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
      $element['warning']['#markup'] = $this->t('Unable to load the referenced entity.');
      return $element;
    }

    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $item->entity;

    if (isset($widget_state['entities'][$delta]['entity'])) {
      $entity = $widget_state['entities'][$delta]['entity'];
    }

    $op = $entity ? 'edit' : 'add';
    $langcode = $items->getEntity()->language()->getId();
    $parents = array_merge($element['#field_parents'], [
@@ -135,8 +148,11 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
    $values = [];
    foreach ($items as $delta => $value) {
      $element = NestedArray::getValue($form, [$field_name, 'widget', $delta]);
      $inline_form_handler = InlineEntityForm::getInlineFormHandler($element['inline_entity_form']['#entity_type']);
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      $entity = $element['inline_entity_form']['#entity'];
      $inline_form_handler->buildEntity($element['inline_entity_form'], $entity, $form_state);

      $weight = isset($submitted_values[$delta]['_weight']) ? $submitted_values[$delta]['_weight'] : 0;
      $values[$weight] = ['entity' => $entity];
    }
+41 −0
Original line number Diff line number Diff line
<?php

use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_field_widget_complete_form_alter().
 */
function inline_entity_form_test_field_widget_complete_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  $field_definition = $context['items']->getFieldDefinition();

  if ($field_definition->getName() === 'positive_int') {
    /** @var \Drupal\Core\Field\FieldItemListInterface $items */
    $items = $context['items'];
    $element['button'] = [
      '#type' => 'button',
      '#value' => 'Call ajax',
      '#item_values' => $items->getValue(),
      '#limit_validation_errors' => [],
      '#ajax' => [
        'callback' => 'inline_entity_form_test_ajax_handler',
      ],
    ];
    $element['value'] = [
      '#type' => 'textfield',
    ];
  }
}

function inline_entity_form_test_ajax_handler(array $form, FormStateInterface $form_state): AjaxResponse {
  $button = $form_state->getTriggeringElement();
  $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
  $value_field = $element['value'];

  $response = new AjaxResponse();
  $response->addCommand(new InvokeCommand("[name='${value_field['#name']}']", 'val', [$button['#item_values'][0]['value']]));
  return $response;
}
+16 −0
Original line number Diff line number Diff line
@@ -28,8 +28,10 @@ class SimpleWidgetTest extends InlineEntityFormTestBase {

    $this->user = $this->createUser([
      'create ief_simple_single content',
      'create ief_complex_simple content',
      'create ief_test_custom content',
      'edit any ief_simple_single content',
      'edit any ief_complex_simple content',
      'edit own ief_test_custom content',
      'view own unpublished content',
      'create ief_simple_entity_no_bundle content',
@@ -209,6 +211,20 @@ class SimpleWidgetTest extends InlineEntityFormTestBase {
    $assert_session->elementExists('xpath', $nested_title_field_xpath);
  }

  /**
   * Tests that the form is rebuild properly on an ajax requesz.
   */
  public function testFormRebuildOnAjaxRequest() {
    $this->drupalLogin($this->user);
    $this->drupalGet('node/add/ief_simple_single');

    $this->getSession()->getPage()->fillField('single[0][inline_entity_form][positive_int][0][value]', 1);
    $this->getSession()->getPage()->pressButton('Call ajax');
    $this->assertSession()->assertWaitOnAjaxRequest();

    $this->assertSession()->fieldValueEquals('single[0][inline_entity_form][positive_int_wrapper][value]', 1);
  }

  /**
   * Ensures that an entity without bundles can be used with the simple widget.
   */