在表之间拖动行 [英] Dragging rows between tables

查看:107
本文介绍了在表之间拖动行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个想法很简单,几乎可以奏效.有两个表,用户可以选择在两个表之间拖动行.当将一行从table1拖到table2时,使用ajax来用从table1删除的数据更新数据库,将其添加到table2,并用新数据重新显示两个表.如果将信息从table2拖到table1,同样的事情也会起作用.

The idea is pretty simple and it almost works. There are two tables and the user has the option of dragging rows between the two tables. When a row is dragged from table1 to table2, ajax is used in order to update the database with the data that is removed from table1, added to table2, and to re-display both of the tables with the new data. The same thing works if information is dragged from table2 to table1.

您可以在此处看到代码示例.

You can see a sample of the code here.

以下是其中一个表的Javascript代码摘录:

Here is an excerpt of the Javascript code for one of the tables:

var startTable = "table1";
var $tabs=$("#" + startTable);
$( "tbody.connectedSortable")
.sortable({
    connectWith: ".connectedSortable",
    items: "> tr:not(:first)",
    appendTo: $tabs,
    helper:"clone",
    cursor:"move",
    zIndex: 999990
})
.disableSelection()
;
$($tabs).droppable({
    accept: ".connectedSortable tr",
    hoverClass: "ui-state-hover",
    drop:function(event, ui){
        var start= ui.draggable.attr("id");
        var desTable = $(this).attr("id");
        if(start != desTable){
            alert("The ajax should be called");
        }
        return false;
    }
});

除了一种情况下,它都能正常工作.如果将一行从Table1拖到Table2,它将创建一个插槽以显示放开该行时将在何处插入该行.换句话说,如果用户将一行从Table1拖到Table2的最后一个元素,它将创建一个开放的占位符(在Table2的最后一行之下),以描述放行时行将移向何处.这有一个问题.如果创建了占位符,但随后将该行拖到表的外部并放开,则该行仍会转到占位符,但从不调用draggable属性.

It works perfectly except for just one case. If a row is being dragged from Table1 to Table2, it creates a slot to show where the row will be inserted when the row is let go. In other words, if a user drags a row from Table1 to the last element of Table2, it creates an open place-holder (under the last row in Table2) to depict where the row will go when let go. There is one problem with this. If the place-holder is created but the row is then dragged outside of the table and let go, the row still goes to the place-holder but the draggable property is never called.

我想发生的事情是,如果创建了一个占位符,那么无论该行放到哪里,它都会转到该占位符,并调用与其放入的表相对应的可放置代码.如果不存在占位符,则该行应返回到其拖动位置,并且什么也不会发生.

What I would like to happen is if a place-holder is created, no matter where the row is let go, it will go to the place-holder and call the droppable code that corresponds to the table it was dropped in. If no place-holder is present, the row should go back to where it was dragged from and nothing should happen.

我尝试过的每个示例都在两个表之间拖动行具有相同的问题.你们有什么方法可以调用可删除的代码,即使该行已被删除到表之外?还是有一种更好的方法来调用ajax,而不是将行放在表上时?任何见识将不胜感激.

Every example I've tried that drags rows between two tables has the same problem. Do you guys have any way to call the droppable code even if the row is being dropped outside of the table? Or maybe there is a better way to call ajax rather than when the row is dropped on the table? Any insight would be greatly appreciated.

推荐答案

要在行从一个表拖放到另一个表时触发ajax请求,可以使用的/sortable/#event-receive"rel =" noreferrer> 接收 事件sortable 小部件.

For triggering an ajax request when a row is dropped from one table to another you can use the receive event of sortable widget.

将已连接的可排序列表中的项目放入另一个列表时,将触发此事件.后者是事件的目标.

This event is triggered when an item from a connected sortable list has been dropped into another list. The latter is the event target.

(强调我的)

更新了小提琴(部分结果,请参见下面的代码段作为最终演示 >)

在接收回调中,您可以使用第二个参数(ui.item)的item属性访问删除的行.

Inside the receive callback, you can access the dropped row using the item property of second argument (ui.item).

如果触发了接收事件回调,则表示ui.item已添加到this表($(this).closest("table.mytable"))中,并已从另一个表($("table.mytable").not($(this).closest("table.mytable")))中删除.然后,您可以相应地触发ajax请求.

If the receive event callback is triggered, it means ui.itemhas been added to this table ($(this).closest("table.mytable")) and removed from the other table ( $("table.mytable").not($(this).closest("table.mytable"))). You can then trigger the ajax request(s) accordingly.

通过这种方式,您不必手动检查是否在同一张表中发生了删除操作(如果您使用的是

By doing it this way, you don't have to manually check whether drop happened within the same table or not (You'll have to do this if you're using update event as someone suggested).

此刻,您不必要使用以下方法初始化可排序对象两次:

At the moment, you're unnecessarily initializing the sortable twice with:

$( "tbody.connectedSortable").sortable({
    connectWith: ".connectedSortable",
    items: "> tr:not(:first)",
    appendTo: $tabs,
    helper:"clone",
    cursor:"move",
    zIndex: 999990
})

$("tbody.connectedSortable").sortable({
    connectWith: ".connectedSortable",
    items: "> tr:not(:first)",
    appendTo: $tabs2,
    helper:"clone",
    cursor:"move",
    zIndex: 999990
});

选择器tbody.connectedSortable适用于两个表,因此它将简单地覆盖先前的初始化.结果,克隆帮助程序将始终附加到第二个表($tabs2).它可能不是您想要的-从其外观上,您仅将克隆附加到各自的父级而进行了两次初始化. appendTo 选项的默认值为"parent",只是将其从初始化中删除将完成这项工作.

The selector tbody.connectedSortable is applicable to both tables, hence it'll simply override the previous initialization, As the result, the clone helper will be always appended to the second table ($tabs2). It is probably not what you want - from the looks of it you're initializing twice just for appending the clone to respective parent. The default value of appendTo option is "parent", just removing it from initialization will do the job.

此外,将标头行从<tbody>移到<thead>元素也是一个好主意,这样您就可以避免指定items: "> tr:not(:first)":由于jQuery UI没有,它在语义上也更好,并且在性能上稍好一些.如果未指定该选项,则不必搜索无效项.

Also, it is a good idea to move the header rows from <tbody> into <thead> element so that you can avoid specifying items: "> tr:not(:first)" : it is more semantic as well as slightly better for performance since jQuery UI doesn't have to search for invalid items if that option is not specified.

最后,您复制了无效的id.要对一组元素进行分组,请改用通用类.

Finally, you've duplicate id's which is invalid. For grouping a set of elements, use a common class instead.

$(document).ready(function() {
  $("tbody.connectedSortable").sortable({
    connectWith: ".connectedSortable",
    helper: "clone",
    cursor: "move",
    zIndex: 99999,
    receive: function(event, ui) {
      /* here you can access the dragged row via ui.item
         ui.item has been removed from the other table, and added to "this" table
      */
      var addedTo = $(this).closest("table.mytable"),
        removedFrom = $("table.mytable").not(addedTo);
      alert("The ajax should be called for adding to " + addedTo.attr("id") + " and removing from " + removedFrom.attr("id"));
    }
  });
});

.mytable a:link,
.mytable a:visited {
  color: #fff;
  font-weight: bold;
  text-decoration: none;
}
.mytable a:active,
.mytable a:hover {
  color: #bd5a35;
  text-decoration: underline;
}
table.mytable {
  width: 90%;
  font-family: Arial, Helvetica, sans-serif;
  color: #666;
  margin-left: auto;
  margin-right: auto;
  font-size: 12px;
  background: #eaebec;
  border: #ccc 1px solid;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
  -moz-box-shadow: 10px 10px 5px #888;
  -webkit-box-shadow: 10px 10px 5px #888;
  box-shadow: 10px 10px 5px #888;
}
.mytable th {
  color: #fff;
  padding: 21px 25px 22px 25px;
  border-top: 1px solid #fafafa;
  border-bottom: 1px solid #e0e0e0;
  background: #191970;
}
.mytable th:first-child {
  text-align: center;
  padding-left: 20px;
}
.mytable tr {
  text-align: center;
  padding-left: 20px;
}
.mytable tr td:first-child {
  text-align: center;
  padding-left: 20px;
  border-left: 0;
}
.mytable tr td {
  padding: 18px;
  border-top: 1px solid #ffffff;
  border-bottom: 1px solid #e0e0e0;
  border-left: 1px solid #e0e0e0;
  background: #fafafa;
  background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafa fa));
  background: -moz-linear-gradient(top, #fbfbfb, #fafafa);
}
.mytable tr.even td {
  background: #f6f6f6;
  background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6 f6));
  background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6);
}
.mytable tr:last-child td {
  border-bottom: 0;
}
.mytable tr:last-child td:first-child {
  -moz-border-radius-bottom-left: 3px;
  -webkit-border-bottom-left-radius: 3px;
  border-bottom-left-radius: 3px;
}
.mytable tr:last-child td:last-child {
  -moz-border-radius-bottom-right: 3px;
  -webkit-border-bottom-right-radius: 3px;
  border-bottom-right-radius: 3px;
}
.mytable tr:hover td {
  background: #f2f2f2;
  transform: scale(1.01);
  padding-left: 20px;
  outline: 1px solid #191970;
  -moz-box-shadow: 10px 10px 5px #888;
  -webkit-box-shadow: 10px 10px 5px #888;
  box-shadow: 10px 10px 5px #888;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<table id='table1' class="mytable">
  <thead>
    <tr class="table1">
      <th>col1</th>
      <th>col2</th>
      <th>col3</th>
      <th>col4</th>
    </tr>
  </thead>

  <tbody class="connectedSortable">

    <tr class="table1">
      <td>a</td>
      <td>b</td>
      <td>c</td>
      <td>d</td>
    </tr>
    <tr class="table1">
      <td>e</td>
      <td>f</td>
      <td>g</td>
      <td>h</td>
    </tr>
  </tbody>
</table>
<table id='table2' class="mytable">
  <thead>
    <tr class="table2">
      <th>COL1</th>
      <th>COL2</th>
      <th>COL3</th>
      <th>COL4</th>
    </tr>
  </thead>
  <tbody class="connectedSortable">

    <tr class="table2">
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr class="table2">
      <td>5</td>
      <td>6</td>
      <td>7</td>
      <td>8</td>
    </tr>
  </tbody>
</table>

侧面说明:我已经组合了类似的CSS类

jQuery UI 1.9+

这篇关于在表之间拖动行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆