Support for Inline Entity Form

Created on 28 February 2017, over 7 years ago
Updated 16 March 2024, 8 months ago

Problem/Motivation

When an inline entity form is used to create content, the conditional_field.js is not loaded and the conditional field rules do not run.

Steps to reproduce

  1. Download Drupal 8.9.0 , Inline Entity Form 8.x-1.0-rc6 ; and clone Conditional Fields branch 8.x-1.x (when I wrote this, the latest commit was 9c9930e)
  2. Install Drupal using the Standard install profile. When that is done, install Conditional Fields and Inline Entity Form
  3. Go to /admin/structure/types/manage/article/fields, add a Boolean field named "Has image" (machine name field_has_image)
  4. Go to /admin/structure/types/manage/article/conditionals and add a condition/dependency as follows:
    1. Target field = field_image
    2. Controlled by = field_has_image
    3. The target field = visible
    4. when the control field is Checked
    5. Click Add dependency
  5. Go to /node/add/article. Observe that when "Has image" is unchecked, the "Image" field is hidden; and when "Has image" is checked, the "Image" field is shown.
  6. Go to /admin/structure/types/manage/page/fields, add a field of type [Entity] Reference to entities of type Content named "Related article" (machine name field_related_article). Use the default configuration.
  7. Go to /admin/structure/types/manage/page/form-display and change the widget from the default to Inline entity form - Simple. Click Save
  8. Go to /node/add/page:
    • Actual behavior: Observe that the "Image" field is always shown regardless of the state of the "Has image" field.
    • Expected behavior: When "Has image" is unchecked, the "Image" field is hidden; and when "Has image" is checked, the "Image" field is shown

Analysis

As originally mentioned in #1, the conditional_fields.js file is missing, and the drupalSettings JSON which controls it is missing (the drupalSettings JSON for the working article form is...

"conditionalFields": {
  "effects": {
    "#edit-field-image-wrapper": []
  }
},

)

The missing library and drupalSettings is because conditional_fields_form_after_build() doesn't attach the libraries. It doesn't attach the libraries because it doesn't detect any conditional fields. Notably, though, it only runs for the outer form (i.e.: the basic page form in the steps to reproduce). It doesn't detect any conditional fields because $this->form['#conditional_fields'] does not exist in the outer form. $this->form['#conditional_fields'] is not added to the outer form because conditional_fields_element_after_build() doesn't detect that the outer form is associated with the inner form's entity/bundle. conditional_fields_element_after_build() detects whether a form is associated with an entity/bundle by calling $form_state->getBuildInfo()['callback_object']->getEntity().

Proposed resolution

Inject information about the inner form's entity so that it can be detected when conditional_fields_element_after_build() runs for the outer form.

Remaining tasks

  1. (done as of #27)
  2. Update the patch from #27 to identify the correct element to attach conditional field actions to.
  3. Statically cache DependencyHelper for different entity types / bundles: #1161314-235: Add basic Field Group support for ANDing conditions
  4. Review and feedback
  5. RTBC and maintainer feedback
  6. Commit and release

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

To be determined.

Feature request
Status

Fixed

Version

4.0

Component

Compatibility w/ other modules

Created by

🇺🇸United States Topplestack Rural, Idaho

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update over 1 year ago
    44 pass, 12 fail
  • 🇮🇳India saurabh-2k17

    Hi, I have updated the patch with the changes from #74 and #79 including few other changes to make it work.
    Please find patch and interdiff attached, Thanks

  • The last submitted patch, 80: 2856720-support_for_inline_entity_form-80.patch, failed testing. View results
    - codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

  • Issue was unassigned.
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update over 1 year ago
    130 pass
  • 🇮🇳India saurabh-2k17

    Hi, I updated the patch with some changes.

  • 🇬🇧United Kingdom welly

    I don't know if it's related to the patch but I'm getting the following error when I applied it.

    TypeError: Drupal\conditional_fields\ConditionalFieldsFormHelper::elementAddProperty(): Argument #1 ($element) must be of type array, null given, called in /var/www/html/web/modules/contrib/conditional_fields/src/ConditionalFieldsFormHelper.php on line 208 in Drupal\conditional_fields\ConditionalFieldsFormHelper->elementAddProperty() (line 888 of modules/contrib/conditional_fields/src/ConditionalFieldsFormHelper.php).
    
  • Status changed to Needs work over 1 year ago
  • 🇬🇧United Kingdom welly
  • Here's a re-roll of patch #83 for the latest 4.0.0-alpha5 release.

  • Just uploading another patch that fixes a part in afterbuild where it wasn't getting the right entity bundle.

    Does this patch work for anybody out there? It's currently not working for us, and we're working on getting it to work. Just curious if there's anyone out there that this patch is working for.

  • 🇨🇦Canada joelpittet Vancouver

    Just for context on the above interdiff in #87.

    -          $bundle = $form['#bundle'] ?? FALSE;
    -          $entity_type = $form['#entity_type'] ?? FALSE;
    +          $ief_entity = $form["#entity"];
    +          $bundle = $ief_entity->bundle();
    +          $entity_type = $ief_entity->getEntityTypeId();
    

    Our $form['#bundle'] was null and thus FALSE. This is for a custom entity type. Grabbing it from the $form["#entity"] gave it the right value (as is similar but not the same to the current code outside of IEF).

    We are playing with the idea of simplifying the code paths be removing:

    -    $form = &$form_state->getCompleteForm();
    +    $full_form = &$form_state->getCompleteForm();
    

    And letting the $form variable be unchanged.

    and

       public function loadDependencies($entity_type, $bundle) {
    -    static $dependency_helper;
    -    if (!isset($dependency_helper[$entity_type][$bundle])) {
    -      $dependency_helper[$entity_type][$bundle] = new DependencyHelper($entity_type, $bundle);
    +    static $dependency_helpers;
    +    $dependency_key = $entity_type . '.' . $bundle;
    +    if (!isset($dependency_helpers[$dependency_key])) {
    +      $dependency_helpers[$dependency_key] = new DependencyHelper($entity_type, $bundle);
         }
    -    return $dependency_helper[$entity_type][$bundle]->getBundleDependencies();
    +    return $dependency_helpers[$dependency_key]->getBundleDependencies();
       }
    

    Looks to be unneeded since the reroll in #86.

  • This patch gets it working for us.
    Inside the getState method of ConditionalFieldsFormHelper, when you use $form_state to grab the entity , it gives you the entity from the main form, rather than the entity inside the inline entity form (the entity being referenced). This patch fixes that.

  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update about 1 year ago
    130 pass
  • Open in Jenkins → Open on Drupal.org →
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 8
    last update about 1 year ago
    130 pass
  • Status changed to Needs review about 1 year ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update about 1 year ago
    130 pass
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update about 1 year ago
    130 pass
  • Status changed to RTBC 11 months ago
  • 🇮🇳India Megha_kundar

    Working as expected
    Thank you very much for patch !!
    Hence moving to RTBC.

  • Status changed to Needs work 9 months ago
  • 🇬🇧United Kingdom very_random_man

    This patch in #89 causes the following error when trying to use Config Split to edit a config split setting.

    Error: Call to a member function bundle() on null in Drupal\conditional_fields\ConditionalFieldsElementAlterHelper->afterBuild() (line 64 of modules/contrib/conditional_fields/src/ConditionalFieldsElementAlterHelper.php).
    

    Removing the patch allows it to work.

  • 🇨🇦Canada joelpittet Vancouver

    @very_random_man maybe you can provide more info? We use config_split also. What version and what config was being split? Maybe we can reproduce the error and fix it. Thabks

  • 🇬🇧United Kingdom very_random_man

    Apologies for the terse response. :-)

    I'm not sure it's specific to the config. I get the error when just trying to edit the config split entity at /admin/config/development/configuration/config-split/[ id ]/edit

    I'm using Config Split 1.9.0 on Drupal 10.2.1.

    This is the complete backtrace:

    Error: Call to a member function bundle() on null in Drupal\conditional_fields\ConditionalFieldsElementAlterHelper->afterBuild() (line 64 of modules/contrib/conditional_fields/src/ConditionalFieldsElementAlterHelper.php).
    conditional_fields_element_after_build(Array, Object)
    call_user_func_array('conditional_fields_element_after_build', Array) (Line: 1084)
    Drupal\Core\Form\FormBuilder->doBuildForm('config_split_edit_form', Array, Object) (Line: 1076)
    Drupal\Core\Form\FormBuilder->doBuildForm('config_split_edit_form', Array, Object) (Line: 1076)
    Drupal\Core\Form\FormBuilder->doBuildForm('config_split_edit_form', Array, Object) (Line: 1076)
    Drupal\Core\Form\FormBuilder->doBuildForm('config_split_edit_form', Array, Object) (Line: 579)
    Drupal\Core\Form\FormBuilder->processForm('config_split_edit_form', Array, Object) (Line: 325)
    Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
    Drupal\Core\Controller\FormController->getContentResult(Object, Object) (Line: 39)
    Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult(Object, Object)
    call_user_func_array(Array, Array) (Line: 123)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 627)
    Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
    Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 32)
    Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
    Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
    Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
    

    Having now had a look in the code, it looks like the `findInlineEntityFormParentsForElement` method is getting confused and incorrectly identifying a checkbox element instead of an inline_entity_form on the basis that it is called 'inline_entity_form'. I would assume that this is because the config split form has a checkboxes for each module.

    I think the solution would be to check to see if the parent IEF form is actually a form and not a form element as part of `findInlineEntityFormParentsForElement`, rather than just assuming that is only IEF forms are called 'inline_entity_form'.

  • Thanks for reporting this @very_random_man and thanks for that info. I think you're right, it does need a check to make sure it's an inline entity form. We've implemented this in this new patch.

  • Status changed to RTBC 9 months ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update 9 months ago
    130 pass
  • 🇬🇧United Kingdom very_random_man

    Nice one, thanks! That definitely does the job. :-)

  • Open in Jenkins → Open on Drupal.org →
    Core: 10.2.x + Environment: PHP 8.1 & MariaDB 10.3.22
    last update 9 months ago
    130 pass
  • 🇫🇷France dqd London | N.Y.C | Paris | Hamburg | Berlin

    What a long issue and patch history! +1 for all the hardwork in here.

    Review/Testing now for commit ...

  • 🇫🇷France dqd London | N.Y.C | Paris | Hamburg | Berlin

    Proposed resolution

    Inject information about the inner form's entity so that it can be detected when conditional_fields_element_after_build() runs for the outer form.

    Seems still valid but the patch kindof changed over time(?), so we need to change the title accordingly before commiting this change, since the original title is too random to track down possible follow ups. Thoughts for a better title from the latest patch authors?

  • 🇫🇷France dqd London | N.Y.C | Paris | Hamburg | Berlin

    Hm ... to speed things up here (this issue has run long enough) I take my own consideration into account. Especially because

    When an inline entity form is used to create content, the conditional_field.js is not loaded and the conditional field rules do not run.

    clearly states that IEF hasn't been supported yet before. And I do not see any documented support for IEF in this project before mentioned. I will set this issue to FR now.

    But I see a lot of issues with the same scope not linked here yet, like:
    #2193025: Inline Entity Form compatibility
    #1941814: Conditional Field doesn't validate my form with inline entity form
    #2188977: Inline Entity Form field cannot be dependent (error when used with IEF module)
    #3079723: Compatibility with Inline Entity Form
    #2892321: About using an inline Entity form with the [visible option]

    Some of them I will surely close in favour of this one here.

    • dqd committed 7ec4b704 on 4.x authored by ramil g
      Issue #2856720 by Murz, ramil g, lexsoft, ChrisDarke, saurabh-2k17,...
  • Status changed to Fixed 9 months ago
  • 🇫🇷France dqd London | N.Y.C | Paris | Hamburg | Berlin
    • dqd committed f988abcf on 4.x
      Remove patch file accidently left in file tree from issue #2856720.
      
  • 🇫🇷France dqd London | N.Y.C | Paris | Hamburg | Berlin

    Addendum: Removed patch file accidently left in file root from latest commit. Too many terminals open today to clean up the issue queue...

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024