There's a longstanding request to allow deleting items in the simple widget. However, this is really an issue with Drupal fields themselves, not inline_entity_form. It's also an issue which multiple_fields_remove_button almost solves.

I found that when using multiple_fields_remove_button the last item in the inline_entity_form simple widget was always deleted in addition to the selected item. After much debugging this seems to be because the simple widget's extractFormValues() method overwrites weights of 0 under some circumstances, causing the last item with a weight of 0 to be overwritten by multiple_fields_remove_button's empty item also with a weight of 0. This might also have other side-effects for other modules which manipulate items/item order like multiple_fields_remove_button.

It's pretty simple to fix this in inline_entity_form - just a matter of deciding a fallback weight more dynamically. I'll attach a patch shortly.

Comments

Dylan Donkersgoed created an issue. See original summary.

dylan donkersgoed’s picture

Status: Active » Needs review
StatusFileSize
new1.38 KB

Patch attached.

geek-merlin’s picture

Chapeau for debugging this!

Code looks good to me, just some nits:

  1. +++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
    @@ -133,11 +133,13 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
    +      $weight = isset($submitted_values[$delta]['_weight']) ? $submitted_values[$delta]['_weight'] : $fallback_weight;
    

    Since D8.7 we can rely on PHP7's ?? operator...!

  2. +++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
    @@ -133,11 +133,13 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
    +    $fallback_weight = 0;
    

    The code is more self-explaining if we say $last_seen_weight=-1 and then $weight=...??$last_seen_weight+1;

wil2091’s picture

#2 works well. Thanks for the patch.

dunebl’s picture

#2 rock... many thanks!

geek-merlin’s picture

Robustified the code....

geek-merlin’s picture

Hah, missed updating the start value. Tweaked var name.

jayemel’s picture

#7 doesn't work for me in the following scenario.

A has a multi-value field reference to B which uses a complex form. B has a multi-value field reference to C which uses a simple form.

A > B (Complex Form) > C (Simple Form).

If I go to entity B and remove C items, works as expected.

If I got to entity A, expand B and then try to remove C items, it doesn't work correctly. It always seems to remove the last item in the list or no items at all, or all of the items.

geek-merlin’s picture

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

@jmljunior: If #7 does not work for you, does #2?

hctom’s picture

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

#2 works for our case, but #7 does not. it always errors out with Notice: Undefined offset: 2 in Drupal\inline_entity_form\Plugin\Field\FieldWidget\InlineEntityFormSimple->extractFormValues().

As far as I see, using the null coalesce operator is just wrong in #7.

+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
@@ -133,11 +133,16 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
+      $weight = $submitted_values[$delta]['_weight'] ?? ++$max_seen_weight;

Above that in the newly introduced loop you already use the value of $submitted_values[$delta]['_weight'], which implies it is not necessarily NULL:

+++ b/src/Plugin/Field/FieldWidget/InlineEntityFormSimple.php
@@ -133,11 +133,16 @@ class InlineEntityFormSimple extends InlineEntityFormBase {
+    $max_seen_weight = -1;
+    foreach ($items as $delta => $value) {
+      $max_seen_weight = max($max_seen_weight, $submitted_values[$delta]['_weight']);
+    }

I guess something like this may be better better?!

$weight = $submitted_values[$delta]['_weight'] ?: ++$maximum_weight;
hctom’s picture

Just checked the behavior with the ?: operator, but this also errors out. I guess the problem is to use the max weight and increase that instead of just increasing a fallback weight as #2 does.

So, we'll stick with #2 ;)

dunebl’s picture

#2 and #7 doesn't apply anymore on last dev or on rc14

steffenr’s picture

Attached the re-rolled patch from #2 against latest dev version of inline_entity_form.

josephcheek’s picture

Hello, #13 doesn't apply on the latest 2.0.0-rc5 due to (I think) the merge of https://www.drupal.org/project/inline_entity_form/issues/3097411 , but I am not clear whether this patch is still necessary now that 3097411 is fixing the weight problem on its own. I am using multiple_fields_remove_button and have found that I cannot remove the entity reference when there is only one entity remaining in my multiple fields. So, it used to be that the last one was always removed, and now it can never be removed?

dcam’s picture

Status: Needs work » Closed (outdated)

Drupal 10.2 added the Remove button to multiple-valued fields. See #1038316: Allow for deletion of a single value of a multiple value field. I tested the button and it worked well for me.

If you experience issues with the default Remove button, then please open a new issue.