Problem/Motivation

When the "Hide when field is not empty" option is enabled for a multivalue field, it prevents additional items from being added correctly in the node edit form

Steps to reproduce

  1. Install a fresh Drupal 11 instance.
  2. Create a Basic page content type.
  3. Add a multivalue text field to the content type.
  4. Create a new Basic page node.
  5. Click "Add another item" → a second field item is added correctly.
  6. Install and enable the module.
  7. Go to Manage form display for the Basic page content type.
  8. Enable "Hide when field is not empty" for the multivalue text field.
  9. Create a new Basic page node.
  10. Click "Add another item".

Actual result

Only one field item is displayed/added instead of 2.

Expected result

Clicking "Add another item" should add a second item, so at least two items are available.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

artyom hovasapyan created an issue. See original summary.

mably’s picture

Assigned: artyom hovasapyan » Unassigned
Priority: Major » Normal
Status: Active » Postponed (maintainer needs more info)

Are you sure it works fine without the module installed?

artyom hovasapyan’s picture

Issue summary: View changes
artyom hovasapyan’s picture

#2 Yes, it works correctly without the module installed.

mably’s picture

Can you provide a full reproducible scenario from a fresh Drupal 11 instance please?

And the corresponding stack trace?

I couldn't reproduce the problem locally.

artyom hovasapyan’s picture

Issue summary: View changes
artyom hovasapyan’s picture

StatusFileSize
new806.18 KB
new635.7 KB

Update description.

mably’s picture

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

Ok, have been able to reproduce the display glitch using this issue's Tugboat instance.

IIUC you need to click twice on the "Add another item" instead of once. Will investigate further.

mably’s picture

Status: Needs work » Needs review

@artyom-hovasapyan it should be fixed.

Can you validate it's fixed in this issue's Tugboat instance?

https://mr1-lqpdvzx0hn6insnsaxzsd0jlpgx0qe0f.tugboatqa.com/

Account: admin / admin

Once validated, I'll publish a new release.

artyom hovasapyan’s picture

@mably Nice 🙂

I tested it and it works as expected, but I couldn’t verify the same functionality when the field is inside a Paragraph.

  • mably committed 2c8d8e20 on 1.x
    fix: #3585946 "Hide when empty" display bug on first click
    
    By: artyom...
mably’s picture

Title: Hide when empty bug » Hide when empty display bug on first click
Status: Needs review » Fixed
Issue tags: -Needs steps to reproduce

Seems to work fine with Paragraphs, merging. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

artyom hovasapyan’s picture

Status: Fixed » Active
StatusFileSize
new468.72 KB

Problem: Paragraph field behavior is inconsistent.

When the field has no items, the “Add new item” button works as expected.
However, if existing paragraph items contain empty values, the “Add new item” functionality breaks and no longer works correctly.

mably’s picture

Status: Active » Postponed (maintainer needs more info)

I'm not sure I understand why it would behave differently within a paragraph.

Could you provide a fully reproducible scenario on a fresh Drupal 11 instance, including detailed steps and the actual result versus the expected result?

EDIT: Looks like I've been able to reproduce the problem shown in your video. Investigating.

artyom hovasapyan’s picture

Paragraph fields use more complex AJAX and entity-based handling than standard multivalue fields, so this difference in behavior might be caused by that additional layer of processing.
I do this on drupla 10.

artyom hovasapyan’s picture

#16 I’ll try to reproduce it on `fresh drupal 11` and ping you back.

artyom hovasapyan’s picture

This problem also exists on a clean Drupal 11 setup.

artyom hovasapyan’s picture

StatusFileSize
new7.89 KB

I created a module similar to yours, and it works. It might be useful to merge some parts, or it could help you improve your implementation.

I also think that if this can be implemented using only a .module hook, the issue might already be fixable at the core level.
What do you think about this patch?

artyom hovasapyan’s picture

StatusFileSize
new87.89 KB

For paragraph fixed but The patch doesn’t work correctly— it also breaks other functionality(when click `add new item` create 2 items).

mably’s picture

Status: Postponed (maintainer needs more info) » Active

Reopening — managed to reproduce the inner-field scenario you described and the previous fix has a real regression there.

Repro

  • Host bundle has a paragraphs reference field (no multi_value_add_hider setting on the outer reference).
  • The paragraph type has an unlimited multi-value text field with hide_empty_add_form = not_empty on its widget.
  • Save a node with one paragraph whose inner item is empty.
  • Edit the node, type a value into the inner input, click the inner "Add another item" — only the original input renders, the new empty one is silently dropped. (If you click "Add another item" without typing first, the click works as expected.)

Root cause

The Apr 22 fix counts non-empty items in the rebuilt $items list and strips the trailing widget when it is empty. On a regular AJAX rebuild that's fine, but on the rebuild produced by the inner field's "Add another" click, the typed value lands in $items[0] as non-empty, the trailing widget our hook tries to add ends up being treated as the empty one to strip, and the freshly added widget the user explicitly asked for is removed.

Fix

Skip the trim entirely when the rebuild was triggered by an _add_more button. Both core's WidgetBase and the Paragraphs widget name their AJAX add buttons with that suffix, so a single str_ends_with($triggering_element['#name'] ?? '', '_add_more') guard covers both. When the user explicitly clicks "Add another", we never strip — the whole point of the click is to expose an extra empty widget.

Tests

Added MultiValueAddHiderParagraphsTest with two methods reproducing the inner-field flow:

  • testInnerAddAnotherWithoutTyping — locks the case you said works.
  • testInnerAddAnotherAfterTypingValue — fails on the pre-fix code, passes with the fix.

Also hardened testTrailingEmptyHiddenAfterFirstValueNotEmptyMode against an intermittent flake observed under load (waits for the second input and the post-submit success message before asserting on them). Three sequential full-suite runs locally are now green and stable.

MR

See !2 on branch 3585946-paragraphs-add-another. Adds drupal/paragraphs to require-dev so CI and downstream contributors can run the new test.

mably’s picture

@artyom-hovasapyan I don't understand your last video, can you explain please?

EDIT: Ok, it might be that in "Always" mode, clicking on "Add more" adds two empty fields. Working on it.

mably’s picture

Status: Active » Needs review

@artyom-hovasapyan can you give it another try please?

I couldn't reproduce any bug locally.

Test coverage has been improved accordingly.

artyom hovasapyan’s picture

StatusFileSize
new585.45 KB

For a simple content type field, everything works correctly.
However, for fields inside paragraphs, the behavior is inconsistent — sometimes it works(when preview field contain text), sometimes it doesn’t.

I’ve also recorded a video to demonstrate the issue.

artyom hovasapyan’s picture

Status: Needs review » Needs work
artyom hovasapyan’s picture

Status: Needs work » Needs review

I tried it, and it worked perfectly! It would be awesome if someone else could test it too.

mably’s picture

Status: Needs review » Active

Quick update — several follow-up scenarios surfaced while validating the fix locally. The MR has been iterated through them and now converges on a single, consistent model. Sharing the model in case it's useful for review.

The model

Each hide_empty_add_form mode falls into one of two categories based on whether should_hide can flip between renders due to user-typed content:

  • Content-conditional modes — not_empty (always), and not_required on a required field (where should_hide = non_empty >= 1 || !required reduces to non_empty >= 1 because !required is FALSE). In these, the trailing empty widget is part of the user's working area as soon as content exists; user-action rebuilds must skip the strip, and the initial-render strip must be paired with an items_count decrement so subsequent clicks don't double-bump the visible count.
  • Constant-TRUE modes — always, and not_required on an optional field. should_hide is always TRUE, so the hook strips on every render. items_count and visible stay in sync naturally and clicks correctly add one row at a time. No decrement here; decrementing in these modes immediately undoes the user's next click.

Both branches converge on the same invariant: every "Add another" click adds exactly one visible row, every "Remove" click drops exactly one row.

Bugs the iteration uncovered

  • not_empty mode + saved-populated paragraph + click was producing two empty fields per click (drift between the initial-render strip and subsequent SKIPs).
  • not_required mode + optional empty + click + type + click was producing 2 visible inputs after the second click instead of 1 (mode contract should hold across clicks).
  • always mode + add-and-fill + click was visibly doing nothing (the early always-mode test only covered the empty-initial single click, not a populated multi-click).
  • always mode + click + type + click cycles where the first click stayed at 1 visible after a misguided items_count decrement on every strip.
  • not_empty mode + Remove on a populated paragraph dropped two rows at once (the strip ran on top of the user-removed delta).
  • not_required mode + required field + type + click silently did nothing (same pattern as the original ticket, in a different mode).

Test coverage

16 methods, 182 assertions, locally green. Each new test was verified to fail on the prior buggy hook with a specific assertion message before the fix was committed.

  • Existing matrix from the previous fix kept and hardened (waits for AJAX-rebuilt elements before asserting).
  • Per-mode regression tests for the bugs above (paragraph context, since most of them only manifest there due to ParagraphsWidget's extractFormValues behavior).

MR

!2 at c9772e2.

Apologies for the noise on the MR — should be stable now. Happy to walk through the model or any specific commit if helpful.

mably’s picture

Status: Active » Needs review
artyom hovasapyan’s picture

Tested, works fine.

mably’s picture

Status: Needs review » Reviewed & tested by the community

Ok, let's merge this!

  • mably committed 0c548e30 on 1.x
    fix: #3585946 Hide when empty display bug on first click (suite)
    
    By:...
mably’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

artyom hovasapyan’s picture

I double check and not work.
Don't hide after content save.

artyom hovasapyan’s picture

Status: Fixed » Needs work
mably’s picture

@artyom-hovasapyan could you please describe in detail the behavior you’re observing so I can reproduce it locally?

May be you could create a dedicated ticket for this new issue?

Unless this is a regression introduced by this issue's fixes ofc.

artyom hovasapyan’s picture

Improved:

This issue is related to this ticket.

Steps to reproduce:

Create a node with a multivalue (unlimited) field and enable the “Hide when field is not empty” option.
Add values to the field and save the content.
Edit the node again.

Result:

An extra empty item appears in the field.

mably’s picture

Sadly, I cannot reproduce your test scenario locally.

Is it from a fresh Drupal 11 instance?

mably’s picture

Status: Needs work » Closed (cannot reproduce)

A new test has been added that implement the described scenario:

https://git.drupalcode.org/project/multi_value_add_hider/-/commit/e5c2be...

The test passes fine.

Closing for now as "Cannot reproduce".

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.