拖放以更改顺序

时间:2010-12-11 06:31:54

标签: jquery jquery-plugins drag-and-drop

我有一些行,并希望为用户提供拖放功能来更改订单。 我该如何实现它?我想这可能与jquery。我也在使用php。

2 个答案:

答案 0 :(得分:2)

结帐jquery UIDraggableDroppableSortable

Sortable就是您正在寻找的东西,但是可拖动和可放置也很好,因为它与可排序功能有很大关系。

如果您想保存任何信息,请循环浏览您必须列出数据的列表,并使用w / Ajax传递它。

答案 1 :(得分:1)

只需要解决这个完全相同的问题,所以不妨在这里添加一些内容,以防它帮助其他人。

jQuery UI Sortable提供了基本的客户端功能,可以很好地重新排序项目,但您仍需要保留订单更改。

我的解决方案是编写一个执行以下操作的JQuery插件:

  • 它为此示例假设了一个表,但只需进行一些更改,它就可以用于列表。
  • 找到表格的tbody元素(Sortable需要tbody,而不是表格,因为它会重新排序直接的子节点。)
  • 如果表格有标题,请插入空白标题栏(请参阅下一步原因)。
  • 将拖动图标占位符*插入为新td(这需要新的列标题)
  • 将sortable应用于目标元素。提供更新函数以捕获拖动更改并将Ajax“PUT”发布到服务器,指定行对象的id,父对象的id以及拖动项目的新排序位置。
  • 插件假定父容器(例如表)具有类似data-id="parentid"的属性,其中parentid是行所属的父项的唯一ID
  • 该插件假设每个显示的行(例如表的tr)都有data-id="itemid"之类的属性,其中itemid是行代表的项目的唯一ID

我的可更新排序函数的简化版本:

update: function (event, ui)
{
    // Get moved row from ui param
    var $target = $(ui.item);

    // Extract the PK of the item just dragged
    var itemId = parseInt($target.attr('data-id'));

    // Extract the PK of the parent of the items
    var parentId = parseInt($target.parent('table').attr('data-id'));

    // Display order is 1-based in my database so add 1
    var index = $target.index() + 1;

    // Send REST call to server to update new display order
    var url = "/api/reorder/" + itemId.toString() + "?order=" + index.toString() + "&parent="+ parentId.toString();
    $.ajax({
        url: url,
        type: "PUT",
        error: function (xhr, status, error)
        {
            alert(url + " " + error);
        },
        success: function (success: bool, status: string, xhr)
        {
            // success is true if all went well server-side
        }
    });
}

服务器端我自己的REST服务是通过MVC API控制器完成的,所以我将概述下面的算法。

服务器端算法:

bool Put(itemId, displayOrder, parentId)
{
    var order = 1;
    var listOfOrderedItems = getAllRecordsSortedByDisplayOrderBelongingTo(parentid);  // Some way of fetching just the set of records belonging to the specified parent id
    foreach (var item in listOfOrderedItems)
    {
         // Skip the new insertion point index
         if (order == displayOrder)
         {
              order++;
         }
         // Skip the item we are moving - it gets a new fixed order
         if (item.id != itemId)
         {
             item.DisplayOrder = order++;  // Could use be a SQL update here
         }
         else
         {
             item.DisplayOrder = displayOrder;  // Could use be a SQL update here
         }
    }
}

最终结果是reorderData插件我可以应用于任何带有jQuery行的表:

$(function () {
    $('table.sortable').reorderData();
});

enter image description here *注意:使用拖动占位符(左侧的3行图标),因为我认为它是糟糕的用户体验,可以通过拖动行中的任何位置来拖动整行数据。通过在Sortable选项中使用cancel: 'tr>td:not(:first-child)',它只允许通过每行的第一个单元格中的新拖动句柄进行拖动。