JQueryUI sortable thead and tbody shrinked while d

2019-02-21 16:00发布

I have a table with different rows and fields. In one row I have two fields with display:none; and when I make the drag of this rows, there is an effect like lateral padding in the <tbody> and the <thead>, the table isn't shrinked, elements of the table yes.

In the next JsFiddle in the first row doesn't work correctly, but in second row which only have one field with display:none; it works.

If have any question ask it.

Errors example enter image description here

Table while dragging:

enter image description here

At first I thought it could be solved by looking for the number of <td> elements with the class .hidden-td (class that has a display: none;) and look for the element with the class .placeholder-style (is the class that has the <tr> that is generated when doing the drag) and add many <td> as there are in the <tr> that I am moving, but not, isn't working.

I know how much fields have clase .hidden-td with this line

var numcells = $('.hidden-td').length;

Problem

I have 9 elements in the first row and in the other I have 8. In my function start() I only hidden one column in my placeholder so when I make the drag of the first row there's one column left without apply the class .hidden-td and that's why there's a space at the end of the columns.

How can I fix this?

https://jsfiddle.net/w52m5ggb/20/

3条回答
啃猪蹄的小仙女
2楼-- · 2019-02-21 16:33

When the placeholder is created, it only takes the number of cell in the row and create an empty row with those cells.

You are adding class hidden-td to nth child 2, so you are hiding one cell. This is OK for rows 2 and up, but not for first row, since you have one more cell in that row. See placeholder for row 2:

<td colspan="1">&nbsp;</td><td colspan="1" class="hidden-td">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td>

For first row:

<td colspan="1">&nbsp;</td><td colspan="1" class="hidden-td">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td><td colspan="1">&nbsp;</td>

What you can do is hide every cell in the placeholder and show only the number you need. This can be done with CSS, like this:

.placeholder-style td {
  display: none;
}

.placeholder-style td:nth-child(-n+7) {
  display: table-cell;
}

Result: https://jsfiddle.net/3g3bt80e/1/

查看更多
3楼-- · 2019-02-21 16:46

You could try the approach in the snippet below.

$("#tabs").tabs();

$("#tbodyproject").sortable({
    items: "> tr",
    appendTo: "parent",
    helper: "clone",
    placeholder: "placeholder-style",
    start: function(event, ui) {
      ui.helper.css('display', 'table');
     // console.log(ui.placeholder.html())
    },
    stop: function(event, ui) {
        ui.item.css('display', '')
    },
    update: function( event, ui ) {
        let newOrder = $(this).sortable('toArray');
        $.ajax({
            type: "POST",
            url:'/admin/projects/updateOrder',
            data: {ids: newOrder}
        })
       .done(function( msg ) {
        location.reload();        
       });
    }
}).disableSelection();
img {
  width: 100px;
}
.hidden-td{
  display:none;
}
.table{
  background-color:green;
  border:0;
  width:100%;
}
.trdrag{
  background-color:yellow;
}
.trdrag.ui-sortable-handle td.tdslug, .trdrag.ui-sortable-handle td.tdslug img{
  text-align:center;
  align-items:center;
  display: table-cell;
  justify-content: center;
}
.trdrag.ui-sortable-handle td.tdslug{
  white-space:normal;
  word-wrap: break-word;
}
.trdrag.ui-sortable-handle td.tdslug img{
  padding-left:1rem;
}
.trdrag.ui-sortable-handle {
  text-align:center;
  align-items:center;
  display: table-row;
  justify-content: center;
  width:100%;
  margin-left: .3rem;
}
  
.thcenter{
  background-color:grey !important;
}
.ui-sortable-helper {
  left:0px!important;
}
.idrow{
  width:5%;
}
.tdvisible{
  width:5%;
}
.tdslug{
  width:10%;
}
.tdimg{
  width:15%;
}
.tdorder{
  width:20%;
}
.tdacciones{
  width:40%;
}

.placeholder-style td {
  display: none;
}

.placeholder-style td:nth-child(-n+7) {
  display: table-cell;
}
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<div id="tabs">
        <div class="col-md-12">
            <div id="table1">
              <table class="table">
                <thead>
                  <tr>
                    <th class="thcenter">ID</th>
                    <th class="thcenter">Visible</th>
                    <th class="thcenter">Nombre</th>
                    <th class="thcenter">Header</th>
                    <th class="thcenter">Home</th>
                    <th class="thcenter">Orden</th>
                    <th class="thcenter"><span class="glyphicon glyphicon-cog"></span>Acciones</th>
                  </tr>
                </thead>
                <tbody id="tbodyproject"> 
                    <tr id="id1" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">1</p></td>
                      <td  class="hidden-td" style="display:none;">Testing</td>
                      <td  class="hidden-td" style="display:none;">Testing2</td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 1</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">
                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 1">Delete
                      </form>
                     </td>
                    </tr>
                     <tr id="id1" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">2</p></td>
                      <td style="display:none;">Testing</td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 1</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">
                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 1">Delete
                      </form>
                     </td>
                    </tr>
                     <tr id="id1" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">3</p></td>
                      <td style="display:none;">Testing</td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 1</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">
                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 1">Delete
                      </form>
                     </td>
                    </tr>
                     <tr id="id1" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">1</p></td>
                      <td style="display:none;">Testing</td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 1</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">
                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 1">Delete
                      </form>
                     </td>
                    </tr>
                     <tr id="id1" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">4</p></td>
                      <td style="display:none;">Testing</td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 1</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">
                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 1">Delete
                      </form>
                     </td>
                    </tr>
                    <tr id="id2" class="trdrag">
                      <td class="idrow tdcenter"><p id="margindata">5</p></td>
                      <td class="tdcenter tdvisible"> 
                        Yes
                      </td>
                      <td class="tdslug"><p id="margindata">Slug</p></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizeheader"></td>
                      <td class="tdimg"><img src="http://via.placeholder.com/350x150" class="sizehome"></td>
                      <td class="tdcenter tdorder"><p id="margindata">Order 2</p></td>
                      <td class="tdacciones">
                      <form method="POST" action="{{route('admin.projects.destroy',$project->id)}}" onsubmit="return ConfirmarBorrar()">

                          <a href="#" class="btn btn-success btn-sm" id="margindata">Edit</a> 
                          <input type="submit" value="Delete" class="btn btn-danger btn-sm" id="margindata">
                          <input type="hidden" name="_token" value="Token 2">Delete
                      </form>
                      </td>
                    </tr>
                </tbody>
              </table>
              <br><br>
            </div>
        </div>

查看更多
戒情不戒烟
4楼-- · 2019-02-21 16:49

Having struggled with the sortable plugin myself for the past few days, I think the following changes need to be done:

  1. Add the helper function to create the correct sizes on the helper (draggable object) to have the correct size.

  2. In the start function, add the item html to the placeholder html, to have the placeholder stay identical to the original.

Code:

$("#tbodyproject").sortable({
    items: "> tr",
    appendTo: "parent",
    helper: "clone",
    placeholder: "placeholder-style",
    start: function(event, ui) {
      $(this).find('.placeholder-style td:nth-child(2)').addClass('hidden-td')

      //copy item html to placeholder html

      ui.placeholder.html(ui.item.html());

      //hide the items but keep the height/width. 
      ui.placeholder.css('visibility', 'hidden');
    },
    stop: function(event, ui) {
        ui.item.css('display', '')
    },

    //add helper function to keep draggable object the same width
    helper: function(e, tr)
    {
        var $originals = tr.children();
        var $helper = tr.clone();
        $helper.children().each(function(index)
        {
        // Set helper cell sizes to match the original sizes
        $(this).width($originals.eq(index).width());
        });
        return $helper;
    },
    update: function( event, ui ) {
        let newOrder = $(this).sortable('toArray');
        $.ajax({
            type: "POST",
            url:'/admin/projects/updateOrder',
            data: {ids: newOrder}
        })
       .done(function( msg ) {
        location.reload();        
       });
    }
}).disableSelection();

Updated fiddle

查看更多
登录 后发表回答