Skip to content

Fix widget preview/field mismatch after drag-and-drop reordering#5307

Draft
Copilot wants to merge 7 commits intomainfrom
copilot/fix-az-ranking-preview-order
Draft

Fix widget preview/field mismatch after drag-and-drop reordering#5307
Copilot wants to merge 7 commits intomainfrom
copilot/fix-az-ranking-preview-order

Conversation

Copy link
Contributor

Copilot AI commented Feb 12, 2026

Description

After drag-and-drop reordering, widget previews displayed incorrect item data when AJAX callbacks triggered form rebuilds (via "Update Preview", "Add Another Item", or "Remove" buttons).

Root cause: The $items array parameter comes from entity storage and remains in database order, even after drag-and-drop reordering. The $delta parameter represents the display position after reordering. The original code incorrectly used $items[$delta], which only worked on initial load. The original_deltas mapping in widget state is only populated during deletion operations (as noted in the original code comment "We may have had a deleted row"), not during reordering operations.

Solution: Build a weight-based mapping from submitted form values to correctly identify which item corresponds to each display position:

  1. Extract weight values from user input ($form_state->getUserInput())
  2. Sort items by weight to create a display-position-to-item-index mapping
  3. Use this mapping to fetch the correct item for each display position
  4. Use the mapped item index for collapse status tracking

Implementation:

public function formElement(...) {
    // Get widget state and initialize item delta
    $item_delta = $delta;
    
    // Extract weight values from form input
    $user_input = $form_state->getUserInput();
    $field_values = NestedArray::getValue($user_input, $field_path);
    
    if (!empty($field_values)) {
        // Build weight-sorted mapping
        $weighted_deltas = [];
        foreach ($field_values as $item_index => $item_value) {
            if (isset($item_value['_weight'])) {
                $weighted_deltas[] = [
                    'delta' => $item_index,
                    'weight' => $item_value['_weight'],
                ];
            }
        }
        
        // Sort by weight and map display position to item index
        usort($weighted_deltas, fn($a, $b) => $a['weight'] <=> $b['weight']);
        if (isset($weighted_deltas[$delta])) {
            $item_delta = $weighted_deltas[$delta]['delta'];
        }
    }
    
    // Fetch item using correct index
    $item = $items[$item_delta];
    $status = $widget_state['open_status'][$item_delta] ?? FALSE;
}

This approach correctly handles all reordering scenarios including:

  • Simple adjacent swaps
  • Complex multi-position moves
  • Add Another Item after reordering
  • Remove after reordering
  • Update Preview after reordering

Affected widgets: AZRankingWidget, AZCardWidget

Release notes

Related issues

How to test

  1. Create a page with Rankings or Cards paragraph
  2. Add multiple items with distinct content (e.g., different images/text)
  3. Test simple reordering: Drag item 1 to position 2, click "Update Preview" → verify previews match fields
  4. Test complex reordering: Drag item 1 to position 3, click "Add Another Item" → verify previews match fields
  5. Test removal: After reordering, add a new item, then remove it → verify previews still match fields
  6. All three buttons (Update Preview, Add Another Item, Remove) should maintain correct preview/field pairing after any reordering pattern

Types of changes

Arizona Quickstart (install profile, custom modules, custom theme)

  • Patch release changes
    • Bug fix
    • Accessibility, performance, or security improvement
    • Critical institutional link or brand change
    • Adding experimental module
    • Update experimental module
  • Minor release changes
    • New feature
    • Breaking or visual change to existing behavior
    • Upgrade experimental module to stable
    • Enable existing module by default or database update
    • Non-critical brand change
    • New internal API or API improvement with backwards compatibility
    • Risky or disruptive cleanup to comply with coding standards
    • High-risk or disruptive change (requires upgrade path, risks regression, etc.)
  • Other or unknown
    • Other or unknown

Drupal core

  • Patch release changes
    • Security update
    • Patch level release (non-security bug-fix release)
    • Patch removal that's no longer necessary
  • Minor release changes
    • Major or minor level update
  • Other or unknown
    • Other or unknown

Drupal contrib projects

  • Patch release changes
    • Security update
    • Patch or minor level update
    • Add new module
    • Patch removal that's no longer necessary
  • Minor release changes
    • Major level update
  • Other or unknown
    • Other or unknown

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My change requires release notes.
Original prompt

This section details on the original issue you should resolve

<issue_title>az_ranking re-order preview issue</issue_title>
<issue_description>## How to reproduce

  1. Create a page, Add Rankings

  2. Fill in the first ranking, just use default settings

  3. "Add another item"

  4. For the second ranking, do "Image Only"

  5. Upload / pick an image

  6. Reorder, by putting the second "Image Only" ranking above the first one.

  7. Click on "Update Preview" anywhere or "Add another item".
    Image

    Result: The ordering of the preview and the corresponding fields get broken.
    Image

Where the Issue Is

In AZRankingWidget.php, the formElement() function handles creation of preview items from the user's input.

This seems to be triggered when 1 of 3 buttons are clicked:

Image
  • Update Preview
  • Add Another Item
  • Remove

If I have 3 rankings showing like this:

    Position 1
    [Preview of Ranking 1]
    [Fields of Ranking 1]
    
    Position 2
    [Preview of Ranking 2]
    [Fields of Ranking 2]
    
    Position 3
    [Preview of Ranking 3]
    [Fields of Ranking 3]

And I reorder it using the drag and drop so that it looks like this:

    Position 1
    [Preview of Ranking 2]
    [Fields of Ranking 2]
  
    Position 2
    [Preview of Ranking 1]
    [Fields of Ranking 1]
    
    Position 3
    [Preview of Ranking 3]
    [Fields of Ranking 3]

And then if i click on "Update Preview" or "Add Another Item", it will look like this:

    Position 1
    [Preview of Ranking 1]
    [Fields of Ranking 2]
  
    Position 2
    [Preview of Ranking 2]
    [Fields of Ranking 1]
    
    Position 3
    [Preview of Ranking 3]
    [Fields of Ranking 3]

Preview of Ranking 1 will show on top of fields of ranking 2. It almost seems like the preview is stuck to its original position even though its corresponding fields have moved: Preview of Ranking 1 is still in position 1, preview of ranking 2 is still in position 2 despite the fact that I've switched the order/position of those items.

If I click on "Remove" (Remove an item) however, somehow that makes everything right again. The correct previews stick to the corresponding fields. There is something wrong with the way Ajax is working for "Update Preview" and "Add Another Item" that causes the form rebuild to put the previews with the wrong fields, but whatever is affecting those two buttons is not affecting the "remove" button.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 12, 2026 22:36
Move item retrieval after original_deltas remapping to ensure preview
uses correct item data when rankings are reordered via drag-and-drop.

Co-authored-by: kevdevlu <[email protected]>
Apply same fix as az_ranking: move item retrieval after original_deltas
remapping to ensure preview uses correct item data when cards are reordered.

Co-authored-by: kevdevlu <[email protected]>
Copilot AI changed the title [WIP] Fix az_ranking re-order preview issue Fix widget preview/field mismatch after drag-and-drop reordering Feb 12, 2026
Copilot AI requested a review from kevdevlu February 12, 2026 22:39
@kevdevlu
Copy link
Member

@copilot Now "Add Another Item" and "Update Preview" now work. But "Remove" doesn't seem to work anymore.

Here's how I tested. I have 3 ranking items in an existing node:

Position 1
[Preview of Item 1]
[Fields of Item 1]

Position 2
[Preview of Item 2]
[Fields of Item 2]

Position 3
[Preview of Item 3]
[Fields of Item 3]

I reorder the items like this:

Position 1
[Preview of Item 2]
[Fields of Item 2]

Position 2
[Preview of Item 1]
[Fields of Item 1]

Position 3
[Preview of Item 3]
[Fields of Item 3]

I click on "Add Another Item". So far so good. The reordering above holds.
Then I remove the new item that i just added. Now it shows:

Position 1
[Preview of Item 1]
[Fields of Item 2]

Position 2
[Preview of Item 2]
[Fields of Item 1]

Position 3
[Preview of Item 3]
[Fields of Item 3]

Preview of Item 1 is now corresponded to Fields of Item 2 in position 1.

Use separate $original_delta variable to fetch item and collapse status
while keeping $delta for form element IDs. This ensures Remove button
works correctly while maintaining fix for Update Preview/Add Another Item.

Co-authored-by: kevdevlu <[email protected]>
Copy link
Contributor Author

Copilot AI commented Feb 12, 2026

@copilot Now "Add Another Item" and "Update Preview" now work. But "Remove" doesn't seem to work anymore.

Here's how I tested. I have 3 ranking items in an existing node:
...

Fixed in commit 2066ef9. The issue was that my previous fix overwrote the $delta variable, which caused problems with form element tracking after removal. Now using separate $original_delta for data fetching while preserving $delta for display position. This ensures all three buttons (Update Preview, Add Another Item, and Remove) work correctly after reordering.

@kevdevlu
Copy link
Member

@copilot The case i specified in the previous comment with the "remove" button still does not work (same faulty behavior as before). On top of that i found another scenario with "Add Another Item" button that doesn't work:

First, I want to say the original case still works:

I have 3 ranking items in an existing node:

Position 1
[Preview of Item 1]
[Fields of Item 1]

Position 2
[Preview of Item 2]
[Fields of Item 2]

Position 3
[Preview of Item 3]
[Fields of Item 3]

I reorder the items like this:

Position 1
[Preview of Item 2]
[Fields of Item 2]

Position 2
[Preview of Item 1]
[Fields of Item 1]

Position 3
[Preview of Item 3]
[Fields of Item 3]

I click on "Add Another Item". This works. The reordering above holds and still works.

But the case where the "Add Another Item" button doesn't work is: if i start with the same 3 ranking items, but drag and drop item 1 into position 3 (instead of position 2).

Start with:

Position 1
[Preview of Item 1]
[Fields of Item 1]

Position 2
[Preview of Item 2]
[Fields of Item 2]

Position 3
[Preview of Item 3]
[Fields of Item 3]

I reorder the items like this:

Position 1
[Preview of Item 2]
[Fields of Item 2]

Position 2
[Preview of Item 3]
[Fields of Item 3]

Position 3
[Preview of Item 1]
[Fields of Item 1]

Then if i click on "Add Another Item", it shows:

Position 1
[Preview of Item 1]
[Fields of Item 2]

Position 2
[Preview of Item 2]
[Fields of Item 3]

Position 3
[Preview of Item 3]
[Fields of Item 1]

The fields are holding to the correct order but the previews of the fields are not positionally associated with the right fields.

Copilot AI and others added 3 commits February 12, 2026 23:42
Instead of relying on original_deltas (which is only for deletions),
build item mapping from submitted weight values. This correctly handles
reordering in all scenarios including complex drag-and-drop patterns.

Co-authored-by: kevdevlu <[email protected]>
Addressed code review feedback by removing the initial $status assignment
that was always overwritten after computing $item_delta.

Co-authored-by: kevdevlu <[email protected]>
Addressed code review feedback by removing trailing whitespace.

Co-authored-by: kevdevlu <[email protected]>
Copy link
Contributor Author

Copilot AI commented Feb 12, 2026

@copilot The case i specified in the previous comment with the "remove" button still does not work (same faulty behavior as before). On top of that i found another scenario with "Add Another Item" but...

Fixed in commits 3870847, a962573, and aa76dad. The previous approach using original_deltas was incorrect because it's only populated during deletion operations, not reordering. The new solution builds a weight-based mapping from submitted form values to correctly identify which item corresponds to each display position. This handles all reordering patterns including complex multi-position moves, plus Add Another Item and Remove operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

az_ranking re-order preview issue

2 participants