Problem/Motivation

In the docs for drupal_attach_tabledrag() it mentions

In a more complex case where there are several groups in one column (such as the block regions on the admin/structure/block page), a separate subgroup class must also be added to differentiate the groups.

I've been trying to get that working with minimal additional JS and I think I might've uncovered some bugs in tabledrag. When trying to use subgroups I was finding that dragging a row from one group into the other didn't seem to copy the subgroup class across correctly.

In #2489826: tabledrag is broken (dcf9ab4) some changes were made to some tabledrag jQuery selectors. I think the changes were meant to be functionally equivelent, just a little more efficient, eg:

-    var $indentationLast = $item.find('td').eq(0).find('.js-indentation').eq(-1);
+    var $indentationLast = $item.find('td:first-of-type').find('.js-indentation').eq(-1);

IIUC the starts of both of those lines basically do the same thing - grab the first td. But there are some other situations where I think the behaviour changed, and I wonder if that was unintentional.

  1. --- a/core/misc/tabledrag.js
    +++ b/core/misc/tabledrag.js
    @@ -718,7 +718,7 @@
             // take into account hidden rows. Skip backwards until we find a draggable
             // row.
             while ($row.is(':hidden') && $row.prev('tr').is(':hidden')) {
    -          $row = $row.prev('tr').eq(0);
    +          $row = $row.prev('tr:first-of-type');
               row = $row.get(0);
             }
             return row;
    

    In this case $row.prev('tr:first-of-type') will only return a value if the previous row is also the first row in the table, rather than iterating each previous row. I've reverted that in the patch, but I wonder if the whole while block is redundant: $row is set from $(this.table.tBodies[0].rows).not(':hidden') at the start of findDropTargetRow().

    @@ -766,9 +766,9 @@
         }
         // Siblings are easy, check previous and next rows.
         else if (rowSettings.relationship === 'sibling') {
    -      $previousRow = $changedRow.prev('tr').eq(0);
    +      $previousRow = $changedRow.prev('tr:first-of-type');
           previousRow = $previousRow.get(0);
    -      var $nextRow = $changedRow.next('tr').eq(0);
    +      var $nextRow = $changedRow.next('tr:first-of-type');
           var nextRow = $nextRow.get(0);
           sourceRow = changedRow;
           if ($previousRow.is('.draggable') && $previousRow.find('.' + group).length) {
    

    This is what caused the original problem and prevented the weight subgroup class being copied over when moving a row into a different group. As before it's looking for the previous row using first-of-type and in this case it means the source row for sibling relationships isn't correctly set. The patch should fix and test this.

    @@ -811,7 +811,7 @@
             // Use the first row in the table as source, because it's guaranteed to
             // be at the root level. Find the first item, then compare this row
             // against it as a sibling.
    -        sourceRow = $(this.table).find('tr.draggable').eq(0).get(0);
    +        sourceRow = $(this.table).find('tr.draggable:first-of-type').get(0);
             if (sourceRow === this.rowObject.element) {
               sourceRow = $(this.rowObject.group[this.rowObject.group.length - 1]).next('tr.draggable').get(0);
             }
    

    The original line found the first row with the draggable class but the modified version looks for a row which is both the first and has the draggble class. This causes an issue with field_group on a table with a non-draggable first row: #3085858: Drag and drop acts weird, sometimes not resetting the parent, or even clearing the region value. The patch should fix and test this.

    This is my first time touching tabledrag so careful review welcome :p

    Also it's quite an old commit that introduced this, I know tabledrag is used in lots of places, so I'm not sure if I'm just missing something obvious... (:

    Proposed resolution

    Replace occurrences of ('tr:first-of-type') with ('tr') in tabledrag.js, for example in this block of code:

    --- a/core/misc/tabledrag.js
    +++ b/core/misc/tabledrag.js
    @@ -718,7 +718,7 @@
             // take into account hidden rows. Skip backwards until we find a draggable
             // row.
             while ($row.is(':hidden') && $row.prev('tr').is(':hidden')) {
    -          $row = $row.prev('tr').eq(0);
    +          $row = $row.prev('tr:first-of-type');
               row = $row.get(0);
             }
             return row;
    

    Remaining tasks

    • Manual testing
    • Code review

    User interface changes

    N/A

    Introduced terminology

    N/A

    API changes

    N/A

    Data model changes

    N/A

    Release notes snippet

    N/A

Issue fork drupal-3089151

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

AndyF created an issue. See original summary.

andyf’s picture

Assigned: andyf » Unassigned
Status: Active » Needs review
StatusFileSize
new6.77 KB
new8.89 KB

Here's a simple change of the JS based on searching for :first-of-type and making sure it wasn't being used with .prev() or .next(). There's more that could be tested but I just wanted to get something replicable first and make sure I'm not imagining things (:

The last submitted patch, 2: 3089151-2-D8--FAIL.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

andyf’s picture

Title: TableDrag subgroups don't copy classes correctly » TableDrag JS :first-of-type issues
Version: 8.8.x-dev » 8.9.x-dev
Issue summary: View changes
Related issues: +#3085858: Drag and drop acts weird, sometimes not resetting the parent, or even clearing the region value
StatusFileSize
new13.42 KB
new11.75 KB
new7.12 KB
new27.35 KB
new31.39 KB

So I was hunting around for any other issues that might be explained/fixed by this. I came across #3085858: Drag and drop acts weird, sometimes not resetting the parent, or even clearing the region value which wasn't fixed by the previous patch, but I poked around a little and it looks like it's caused by another :first-of-type issue I missed the first time around (it's really easy to misread that selector...).

I've managed to recreate the issue by expanding the subgroup test to include parenting, but annoyingly I can't seem to drag the row up and to the left in the test. I've attached two screenshots that show the initial and final state of testParent(). However trying it out manually the new patch seems to fix the issue.


Thanks!

The last submitted patch, 4: 3089151-3-D8.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 4: 3089151-3-D8--FAIL.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

andyf’s picture

Status: Needs work » Needs review
StatusFileSize
new21.32 KB
new21.9 KB
new15.4 KB

The patch from #2769825: Cannot swap tabledrag rows by dragging the lower over the upper row in tests does seem to fix dragging upwards. I've added a hidden group field and expanded the subgroup tests slightly. I wasn't sure what the best way to drag a row as a child of another might be. They need to use different targets depending on whether they're being dragged up or down. In the end I've settled for adding a prefix to the first TD element of each row that adds two stylable spans. One is for dragging a row from below and the other for dragging a row from above. I wonder if there's a neater way?

I've also added a version of the patch which has the fix from #2769825: Cannot swap tabledrag rows by dragging the lower over the upper row in tests folded in, just to confirm the tests pass.

The last submitted patch, 8: 3089151-8-D8.patch, failed testing. View results

The last submitted patch, 8: 3089151-8-with-2769825-D8.patch, failed testing. View results

andyf’s picture

StatusFileSize
new21.4 KB
new21.98 KB
new577 bytes

Oops, need to set a default theme when using the testing profile since The 'testing' install profile's setting of a default theme (Classy) is now deprecated.

The last submitted patch, 11: 3089151-11-D8.patch, failed testing. View results

andyf’s picture

Issue summary: View changes
andyf’s picture

Issue summary: View changes
andyf’s picture

Issue summary: View changes

Update summary: Add task to fix Claro tabledrag

andyf’s picture

Issue summary: View changes

#2769825: Cannot swap tabledrag rows by dragging the lower over the upper row in tests has landed so remove task to wait for it from IS. Also trigger a retest of #11 to check the bare patch now passes.

andyf’s picture

Issue summary: View changes
StatusFileSize
new25.43 KB
new4.24 KB
new18.74 KB

Fix and test Claro tabledrag as well.

The last submitted patch, 17: 3089151-17-D8--FAIL.patch, failed testing. View results

electrokate’s picture

This issue may be related.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

scotwith1t’s picture

andyf’s picture

Issue tags: -tabledrag +tabledrag javascript

👍 Thanks @scotwith1t for the feeback!

Also tagging with javascript, not sure if that's appropriate given it's already the component... ¯\_(ツ)_/¯

andyf’s picture

Issue tags: -tabledrag javascript +tabledrag, +JavaScript

Oops, retagging (:

bnjmnm’s picture

If this issue: #3083051: Refactor tabledrag when core issues are resolved lands, all the Claro changes here can probably be removed. This would make the patch for this issue smaller, and thus easier to review/commit.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

gaëlg’s picture

StatusFileSize
new0 bytes

Here's a try to reroll #17 against 9.2.x (claro tests removed, as advised in #24.

gaëlg’s picture

StatusFileSize
new21.48 KB

Whoops

andyf’s picture

StatusFileSize
new21.13 KB
new3.03 KB

Clean up cspell fails.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

init90’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for the great work! The patch has tests and fixes the related problems with the Field Group module #3085858: Drag and drop acts weird, sometimes not resetting the parent, or even clearing the region value

bnjmnm’s picture

Status: Reviewed & tested by the community » Needs work

This can't be set to RTBC because the most recent patch (#28) is not passing code standard/formatting tests (hence the "custom commands failed" status of the patch). Looks like it is just this

Checking core/tests/Drupal/FunctionalJavascriptTests/TableDrag/TableDragSubgroupTest.php


FILE: ...al/FunctionalJavascriptTests/TableDrag/TableDragSubgroupTest.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 228 | ERROR | Parameter $group is not described in comment
----------------------------------------------------------------------

Time: 155ms; Memory: 6MB
andyf’s picture

Status: Needs work » Needs review
StatusFileSize
new21.18 KB
new629 bytes

Thanks both!

This can't be set to RTBC because the most recent patch (#28) is not passing code standard/formatting tests

Also I don't think it's had a hint of a review, so I think it's a ways away yet anyway.

Here's an updated patch with the missing comment, fingers crossed.

init90’s picture

Status: Needs review » Reviewed & tested by the community
bnjmnm’s picture

Status: Reviewed & tested by the community » Needs work

This isn't a deep review, but in a quick readthrough I spotted a few things that need attention before this is RTBC worthy, but I think this should probably get a deeper review overall:

  1. +++ b/core/modules/system/tests/modules/tabledrag_test/src/Form/TableDragSubgroupTestForm.php
    @@ -0,0 +1,228 @@
    + * If using this as a model for development, note that if you completely empty a
    + * group, it will no longer set the group value correctly if you then try to add
    + * items again (it sets the value based on a sibling). The core block list
    + * builder uses a custom tabledrag.onDrop to set the correct region.
    

    This seems like quite a bit of documentation for an unlikely + unadvisiable scenario. I think this probably adds more noise than it helps. (though I typically prefer erring in the direction of more docs)

  2. +++ b/core/modules/system/tests/modules/tabledrag_test/src/Form/TableDragSubgroupTestForm.php
    @@ -0,0 +1,228 @@
    +      // Set defaults
    

    Needs a period at the end.

  3. +++ b/core/tests/Drupal/FunctionalJavascriptTests/TableDrag/TableDragSubgroupTest.php
    @@ -0,0 +1,262 @@
    +   * @param int|null $weight
    +   *   (optional) The expected weight of the row or NULL to not test the weight;
    +   *   defaults to NULL.
    

    Nit: explicitly specifying (optional) here while next to several other variables that are also optional but not labeled the same way. The (optional) shouldn't be needed since there's a default value in the function signature.

I like that there is added test coverage for the edge cases reported in this issue. It would be good if the review confirmed the tests are fully covering the scenarios impacted by these scenarios, and are doing so in the most efficient possible manner.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

wells’s picture

StatusFileSize
new21.5 KB

Reroll of #32 against 9.4.x-dev. No other changes.

wells’s picture

StatusFileSize
new21.13 KB

Oops. Forgot to build JS in #36... updated patch attached.

Still just a reroll of #32 with no other changes.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

liquidcms’s picture

I was using the patch from #37 to seemingly fix my issue with not being able to place field groups on entity manage display form. This was with core 9.2.16.

I just upgraded core to 9.3.16 and this is now broken again.

and the patch from #31/32 that is listed for 9.3.x does not apply to 9.3.16.. :(

going back to latest patch and i have been able to get my new field group placed correctly by moving it in small steps at a time between saves. certainly still issues with this.

sandeepsingh199’s picture

Status: Needs work » Needs review
StatusFileSize
new21.13 KB

re-rolling the #32 patch for 9.3.x,9.4.x & 9.5.x

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

milos.kroulik’s picture

The patches from #37 and #40 are the same.

wells’s picture

StatusFileSize
new21.26 KB

Here is another re-roll of #32 for 9.5.x.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new144 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

ayush.khare’s picture

StatusFileSize
new19.59 KB
new2.83 KB

Reroll of #43 for 10.1.x

nikhil_110’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This seems like a difficult one to test but from what I can tell it has something to do with parent value.

Tried using the test module provided by the patch. Can it be updated to include parent value as well.

andyf’s picture

Issue tags: -JavaScript +JavaScript

Tried using the test module provided by the patch. Can it be updated to include parent value as well.

Thanks for your time @smustgrave! I'm not really sure what you're asking for here?

Does it really need work rather than review? I tried my best in the IS, there's a test that fails without the patch, it seems to me like NR is appropriate?

Thanks again!

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

heikkiy’s picture

The patch does not seem to apply anymore against core 10.2.

wells’s picture

Status: Needs work » Needs review
StatusFileSize
new19.53 KB

Re-roll of #45 attached for Drupal 10.2.x.

smustgrave’s picture

Status: Needs review » Needs work

Recommend turning to an MR for quicker reviews.

#51 seems to have failures.

Gauravvvv made their first commit to this issue’s fork.

gauravvvv’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

New functions should use type hints and returns.

Also learned we can use constructor promotion.

heikkiy’s picture

I can also confirm that the latest merge request applies against 10.2.

Are there any clear instructions how to repeat the issue without the patch? Would make it easier to test that it works.

I originally applied this patch in our project because we had trouble reordering the fields in the node edit form layout but I also had other related patches applied so I would like to confirm I am testing the right thing.

jsimonis’s picture

heikkiy:

For me, it happens when I am trying to create a set of vertical tabs. So, I create the "tabs" and then the "tab". I drag the tab up under the tabs, then add the content to the tab. Save. The content stays under the tabs item, but the tab has moved down to disabled.

I've tried using the latest patch, but I get:

a "b" folder created in my /web folder
failures in the patch

malcomio’s picture

See #3333953: Nested field groups improperly display as "Disable" in the admin UI for details of an issue affecting the field_group module - the core patch seems to fix that for me.

@jsimonis - how are you applying the patch, and what are the failures that you see when trying to apply the patch?

https://vazcell.com/blog/how-apply-patch-drupal-9-and-drupal-10-composer is a good explanation of how to do this.

loze’s picture

I am seeing the same as @malcomio this patch applies but unfortunately does not fix the issue for me.
I am unable to disable fields using the drag and drop. I need to turn that feature off and select disabled in the dropdown
Drupal 10.4.2
Gin 4.0.2
field_group 3.x-dev

anybody’s picture

Priority: Normal » Major

Setting the priority to major, as this seems to cause a lot of trouble downstream for people using Field Groups heavily: #3085858: Drag and drop acts weird, sometimes not resetting the parent, or even clearing the region value

sleitner made their first commit to this issue’s fork.

sleitner’s picture

Status: Needs work » Needs review

Rerolled and addressed these:

New functions should use type hints and returns.
Also learned we can use constructor promotion.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update, +Needs manual testing

Something noticed is this could use a summary update. With a clear proposed solution. Changing these selectors think will need manual testing as well.

ironnuts’s picture

2x broken functional tests in pipeline.
Test-only test appears good:
https://git.drupalcode.org/issue/drupal-3089151/-/jobs/7086430

ironnuts’s picture

ironnuts’s picture

Issue tags: -JavaScript +JavaScript

Re: #64, applied IS template and re-structured IS, some re-writing for clarity. I updated the 'Remaining tasks' according to #64.

ironnuts’s picture

Issue summary: View changes
Issue tags: -JavaScript +JavaScript
sleitner’s picture

Status: Needs work » Needs review
Issue tags: -JavaScript +JavaScript

Rerolled. The broken funtional tests were random temporary problems.

sleitner’s picture

Issue summary: View changes
Issue tags: -JavaScript +JavaScript

Rerolled

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: -JavaScript +JavaScript, +Needs steps to reproduce

Sorry tried using the summary to figure out the problem but not super clear and want to make sure I'm testing the right scenario. Can the steps to reproduce section be added back to the summary please.

ts.ag made their first commit to this issue’s fork.