This a following issue to a problem introduced by the patch commited in #2489826 : tabledrag is broken

$form['table_a'] = ['#type' => 'table'];
$form['table_a']['row1'] = ...;
$form['table_a']['row1']['column_1'] = .....;
$form['table_a']['row1']['column_1']['table_b'] = ['#type' => 'table'];

Now all the rows of table_b will get a double tabledrag-handle, when makeDraggable is running.
First from the run for table_a and then from the run for table_b!

Until the patch was commited everything was functioning properpy for this kind of nested tables....

And at least this problem appears to be caused by changes in core/misc/tabledrag.js because of exchanging the row

$item.find('td').eq(0).prepend(handle);

with

$item.find('td:first-of-type').prepend(handle);

Comments

davidum’s picture

Issue summary: View changes
davidum’s picture

StatusFileSize
new15.75 KB
new13.52 KB
new13.03 KB

The line $item.find('td:first-of-type').prepend(handle); in tabledrag.js is used to add the handle element to the first td of each as draggable marked tr in a table.
This makes sense in drupal components like Taxonomy or Menu, since all draggable Rows are at the same level within the table, so there is no hierarchical ordering, and the indentation of child elements is just resolved with javascript creating a space for each underlying level. So this is a kind of visual hierarchy, but not real if you look at the code of the table.
For example, Taxonomy is looking like this:
Taxonomy

and the HTML structure of Table body is like this:

<tbody>
   <tr class="draggable odd">TD WITH HANDLE HERE</tr>
   <tr class="draggable even">TD WITH HANDLE HERE</tr>
   <tr class="draggable odd">TD WITH HANDLE HERE</tr>
</tbody>

Beecause of the line

$item.find('td:first-of-type').prepend(handle);

each td within an tr.draggable ($item) being the first td of its parent will get a handle added. This is okay in this case, cause within a tr.draggable there is always just one element matching td:first-of-type.

But sometimes a module would implement a real hierarchical table structure, whith draggable rows containing other draggable rows, like this:

<tbody>
   <tr class="draggable odd">
     TD WITH HANDLE HERE
      ....
       <tr class="draggable odd">TD WITH HANDLE HERE</tr>
       <tr class="draggable even">TD WITH HANDLE HERE</tr>
      ....
   </tr>
</tbody>

Which should look like this:
Hierarchical draggables

Butin this case the line

$item.find('td:first-of-type').prepend(handle);

leads to the situation, that for a top level tr.draggable not only it self but also every child will match the td:first-of-type selector and get a handle element added. Now for the next tr.draggable ($item) found, which will be a child element, there will be a new addition of a handle element, so the child elements will have more than one handle, and ends looking like this:

Hierarchical draggable rows with extra handle

Solution:

Changing the line
$item.find('td:first-of-type').prepend(handle);
back to
$item.find('td).eq(0).prepend(handle);
resolves the problem without affecting the Drupal core implementations. In this case, for each tr.draggable just the first td of all matched ones will get a handle element, preserving child elements to also get a handle when the tr.draggable is a parent element.
For Drupal core implementations like Taxonomy every draggable row will also get a handle element.

davidum’s picture

Status: Active » Needs review
StatusFileSize
new419 bytes
nod_’s picture

Status: Needs review » Reviewed & tested by the community

That does fix the issue. Thanks for the extensive explanation too!

Tabledrag is my new overlay…

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

This issue is a normal bug fix, and doesn't include any disruptive changes, so it is allowed per https://www.drupal.org/core/beta-changes. Committed 962d0c3 and pushed to 8.0.x. Thanks!

  • alexpott committed 962d0c3 on 8.0.x
    Issue #2499605 by davidum, hchonov: tabledrag is adding tabledrag-handle...

Status: Fixed » Closed (fixed)

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