简体   繁体   English

如何在dgrid中使用dnd实现行重新排序

[英]How to implement row reordering with dnd in dgrid

I have created a grid in dgrid that is connected to JsonRest store. 我在dgrid中创建了一个连接到JsonRest存储的网格。 This loads data from pyramid backend. 这会从金字塔后端加载数据。 I have also added DnD extension to the store. 我还在商店中添加了DnD扩展名。 The DnD works, however I don't know how to make it send any meaningful data when I drag the rows. DnD工作,但我不知道如何在拖动行时发送任何有意义的数据。 Currently it sends two requests, one GET and one PUT, but the PUT contains just the data from rows but nothing that I could use to update the order in the database. 目前它发送两个请求,一个GET和一个PUT,但PUT只包含行中的数据,但我没有用来更新数据库中的顺序。

So what configuration is necessary in my grid, so that I can get the new ordering information? 那么在我的网格中需要什么配置,以便我可以获得新的订购信息?

This is what I do: 这就是我做的:

  1. maintain a position column in the database 维护数据库中的position
  2. call store.put when a row is dropped, passing the id of the dropped item and the position it was dropped at. 删除行时调用store.put,传递已删除项的id以及删除它的位置。
  3. When updating the position, shift the other items accordingly 更新位置时,相应地移动其他项目

Here is my onDropInternal function. 这是我的onDropInternal函数。 It handles dropping multiple rows as well: 它还处理丢弃多行:

        onDropInternal: function(nodes, copy, targetItem) {

            var store = this.grid.store, grid = this.grid, targetRow, targetPosition;

            if (!this._targetAnchor) return

            targetRow = grid.row(this._targetAnchor);
            targetPosition = parseInt(targetRow.data[grid.orderColumn]);
            responses = 1;

            nodes.forEach(function(node, idx){
                targetPosition += idx;
                var object = {id:grid.row(node).id};
                object[grid.orderColumn] = targetPosition;
                store.put(object).then(function() {
                        if (responses == nodes.length) grid.refresh();
                        else responses++;
                });
            });

        }

Here's the PHP code I used to update the position. 这是我用来更新位置的PHP代码。 $fields is an associative array representing the record to store. $fields是一个表示要存储的记录的关联数组。 It also assumes the existence of two functions: query and query_row , which I trust you can handle replacing if you choose to utilize this technique. 它还假设存在两个函数: queryquery_row ,我相信如果你选择使用这种技术,你可以处理它。

$table = "my_table";
$field = "position_field";
if (empty($fields['id'])) {
    //for new records, set the position field to the max position + 1
    $h = query_row("SELECT MAX(`$field`) as highest FROM $table LIMIT 1");
    $fields[$field] = $h['highest']+1;
} else if (is_numeric($fields[$field])) {
    //we want to move the row to $target_position
    $target_position = $fields[$field];
    //first get the original position
    $row = query_row("SELECT id,$field FROM $table WHERE id='$fields[id]' LIMIT 1");
    //start a list of ids
    $ids = $row['id'];
    //if the original position is lower than the target postion, set the incrementor to -1, otherwise 1
    $increment = ($row[$field] < $target_position) ? -1 : 1;
    //start a while loop that goes as we long as we have a row trying to take a filled position
    while (!empty($row)) {
        //set the position
        query("UPDATE $table SET $field='$target_position' where id='$row[id]'");
        //get the other row with this position (if it exists)
        $row = query_row("SELECT id,$field FROM $table WHERE id NOT IN ($ids) && `$field`='$target_position' LIMIT 1");
        //add it's id to the list of ids to exclude on the next iteration
        $ids .= ", ".$row['id'];
        //increment/decrement the target position
        $target_position += $increment;
    }
}

You could probably make this more efficient by using a query that updates multiple records at once, but the advantage of this is that it handles unexpected gaps in position numbers well. 您可以通过使用一次更新多个记录的查询来提高效率,但这样做的好处是可以很好地处理位置数的意外缺口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM