Under certain conditions, I see this error: Notice: Undefined index: items_count in Drupal\Core\Field\WidgetBase->formMultipleElements() (line 156 of core/lib/Drupal/Core/Field/WidgetBase.php

Steps to reproduce:

1. Make a content type B with an unlimited value text (or whatever) field.
2. Make a content type A with a single value required entityreference field that allows bundles of type B.
3. Set the form display for the entityreference field to use the Inline Entity Form - Simple widget.
4. On the content type A form, have some kind of AJAX element that will rebuild the form.
5. Create/edit content of type A, and use your AJAX functionality to refresh parts of the form.
6. Save the content.
(Notice should appear)

When WidgetBase is building the form in WidgetBase::form(), it first gets the widget state with WidgetBase::getWidgetState(). If it is empty (such as the first time it is called), it then populates the widget state with array_parents and items_count. That items_count is then relied on to be there, later in form processing. However, something about inline entity form's parent/child forms does not retain items_count.

if you are in EntityInlineForm::entityForm() after the child form is build, then items_count is set and exists in the child form state:
$child_form_state->getStorage()['field_storage']['#parents'][IEF_FIELD_NAME][0]['inline_entity_form']['#fields']['IEF_SUBFIELD_NAME']['items_count']

But when IEF is merging its child form and form state data back into the parent form, this data does not get transferred to its parent form.

By the end of form processing (e.g. in #after_build methods), items_count is always lost. This usually goes unnoticed, except if you have an ajax element on the page. Something about rebuilding the form ends up executing WidgetBase::formMultipleElements() on the parent form, which does not have the widget states of the fields within the inline form.

Full stacktrace:

Notice: Undefined index: items_count in Drupal\Core\Field\WidgetBase->formMultipleElements() (line 156 of core/lib/Drupal/Core/Field/WidgetBase.php).
Drupal\Core\Field\WidgetBase->formMultipleElements(Object, Array, Object)
Drupal\Core\Field\WidgetBase->form(Object, Array, Object)
Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm(Object, Array, Object)
Drupal\Core\Entity\ContentEntityForm->form(Array, Object)
Drupal\pc_metadata\Form\MetadataForm->form(Array, Object)
Drupal\Core\Entity\EntityForm->buildForm(Array, Object)
Drupal\pc_metadata\Form\MetadataForm->buildForm(Array, Object)
Drupal\inline_entity_form\Form\EntityInlineForm->entityForm(Array, Object)
Drupal\inline_entity_form\Element\InlineEntityForm::processEntityForm(Array, Object, Array)
call_user_func_array(Array, Array)
Drupal\Core\Form\FormBuilder->doBuildForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->doBuildForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->doBuildForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->doBuildForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->doBuildForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->processForm('node_episode_form', Array, Object)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object)
Drupal\Core\Entity\EntityFormBuilder->getForm(Object)
Drupal\node\Controller\NodeController->add(Object)
call_user_func_array(Array, Array)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
call_user_func_array(Object, Array)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)e(Object)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jfrederick created an issue. See original summary.

jfrederick’s picture

Status: Active » Needs review
FileSize
1.2 KB

And a patch. I imagine this needs work, but it's working for me so far.

mansspams’s picture

Could you check if other patch in #2612720: Forward port submission improvements (#ief_element_submit) to D8 does the same? That one looks more indepth.

bojanz’s picture

This is technically a duplicate of #2667710: Rewrite the base inline form handling, but lets leave it open until we do that part.

bojanz’s picture

Status: Needs review » Postponed (maintainer needs more info)

#2667710: Rewrite the base inline form handling has landed, there is no more child form state. Can you test tomorrow's -dev?

bojanz’s picture

Status: Postponed (maintainer needs more info) » Closed (duplicate)

Closing, since all of the relevant code is now different.