JSFiddle - React, Tailwind, and code Playground

by ben74

HTML

<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>
<table border=1 class='raye subtab sortable' name='lot'>
<thead class=not><tr>
    <td class=td1>Ord.</td><td class=td2>Tache</td><td class=td3>Charge</td><td class=td4>Poste</td><td class=td5>PPU</td><td class=td6>Total</td><td class=td7>Note</td><td class=td8>Del.</td>
    <td class=tdO>
        <table class=w100><tr class=not><td colspan=4>Achats<hr></td></tr>
            <tr class=not><td class=td9>Prestataire</td><td class=td10>Montant</td><td class=td11>Int.</td><td class=td12>Ext.</td></tr></table>
    </td></tr></thead>
    
<tbody class='sortable lotsel'>
<tr class='dark lot' id='7'><td colspan=9 class='w100'>
 <table class='w100 tachesub'>
  <tr><td class='td1 drag0'>#Lot1</td></tr>
                    
  <tr class='bright'><td class='w100'>
   <table rel='sublist' alt='list1' class='sortable list1'>
    <tr id='5' class='tache'><td class='td1 drag1'>##1</td><td>task1</td><td>-</td></tr>                
    <tr id='6' class='tache'><td class='td1 drag1'>##2</td><td>task2</td><td>-</td></tr>
   </table> 
  </td></tr>
 </table><!--subtab ends-->
</td></tr><!-- lot ends -->
    
<tr class='dark lot' id='8'><td colspan=9 class='w100'>
 <table class='w100'>
  <tr><td class='td1 drag0'>#lot2</td></tr>
                    
  <tr class=bright><td class='w100'>
   <table rel='sublist' alt='list2' class='sortable list2'>
    <tr id='1' class='tache'><td class='td1 drag1'>##1</td><td>task1</td><td>-</td></tr>
    <tr id='2' class='tache'><td class='td1 drag1'>##2</td><td>#2nd</td><td>-</td></tr>
    <tr id='3' class='tache'><td class='td1 drag1'>##3</td><td>#3rd</td><td>-</td></tr>
                            
  </table></td></tr>
 </tr></table><!--subtab ends-->
</td></tr><!-- fin lot -->                 
    
</tbody></table>

CSS

body{color:#000;}
body.dragging, body.dragging * {cursor: move !important;}
.dragged{position: absolute;opacity: 0.5;z-index: 2000;}
select,input,s{display:none;}

.bright{background:#DDD;color:#000;}
.dark{background:#000;color:#FFF}

.sortable .pl{position: relative;}
.sortable .pl td{border:1px dashed #F07;}
.sortable .pl:before{position: absolute;}
.drag1,.drag0{background:#F07;cursor:pointer;}

JavaScript

var list={sortable:{},grp:{a:null}};

$(function(){
    
s1($(".lotsel"),'.lotsel','.lot','<tr class="pl"><td colspan="9"><hr></td></tr>','thead,.tache,.not,.tachesub','.drag0');
//*
$('[rel=sublist]').each(function(){
    var cont='.'+$(this).attr('alt');
    s1($(this),cont,'.tache','<tr class="pl"><td colspan="3"><hr></td></tr>','.lot','.drag1');
});
    
});

function scb(elements,container){
    data=[];
    elements.each(function(){data.push(this.id);});
    console.log(data,container);//[5,6],.tache|.lot
}
function s1(el,cont,sel,pl,ex,drag,callback){
 callback=callback||null;
 list.sortable[cont]=el.sortable({containerSelector:cont,itemSelector:sel,placeholder:pl,exclude:ex,handle:drag,//nested:true,group:cont,
    onDragStart: function ($item, container, _super){
        oldIndex = $item.index();
        $item.appendTo($item.parent());
        _super($item, container);
    },

    onDrop: function  ($item, container, _super) {
        var field,newIndex = $item.index(),elements=$item.closest(cont).find(sel);
        if(newIndex != oldIndex) {
            elements.each(function(i,row){
                row = $(row);
                if(newIndex < oldIndex)row.eq(newIndex).before(row[oldIndex]);
                else if (newIndex > oldIndex)row.eq(newIndex).after(row[oldIndex]);
                //console.log(row.children().eq(newIndex),row.children()[oldIndex]);
            });
        }
        _super($item, container);
        elements=$item.closest(cont).find(sel);
        scb(elements,sel);
    }

   });

}