在线客服

JQuery EasyUI Datagrid 数据表列实现动态拖拽列功能

adminadmin 报建百科 2024-04-25 157 12
JQuery EasyUI Datagrid 数据表列实现动态拖拽列功能

近日用到了EasyUI Datagrid 想要实现一个数据表格列用户可以动态拖拽列(标题栏),拖动后保存到后端数据库中,这样就能满足用户自定义数据表格栏的显示顺序问题。网上搜索了一些代码,感觉不是很完善,拿来改改后实现了自己想要的功能。下面我将分享一下我的使用案例,以便于遇到此类问题的开发者们,能够快速的解决自己的问题。

EasyUI DataGrid是一款基于jQuery和EasyUI框架开发的数据表格组件,它提供了丰富的功能和易用性,使得开发者能够快速地构建出交互性高、效果优美的数据表格页面。通过使用EasyUI DataGrid,开发者可以实现数据的分页、排序、筛选、编辑、删除、新增、复制、导出等功能,同时还可以自定义列头、列宽、单元格样式、单击双击事件等。此外,EasyUI DataGrid还支持本地或远程数据源的加载,并提供了多种数据格式的支持,包括XML、JSON、HTML等。

了解EasyUI的开发者可以自己去引入官方的JS文件,以便完成这项功能demo。

  • jquery.min.js
  • jquery.easyui.min.js
  • jquery.easyui.css

EasyUI 是一个基于 jQuery 的用户界面插件集合,提供了大量的易用的 UI 组件和工具函数。

一、扩展DataGrid插件代码

刚搜到这段代码时,我不知道如何去使用它,自己摸索了一会才有了完善思路。下面给大家讲一讲这段代码的用意,这段代码是通过$.extend扩展了datagrid的一个columnMoving方法,该方法主要实现了easyui datagrid列实现动态拖拽列的功能。具体实现逻辑如下:

    1. 获取datagrid的所有头部单元格,并通过draggable方法将其设置为可拖拽状态。
    1. 对于可拖拽的单元格,设置其proxy属性为一个新创建的div,用来代替拖拽的单元格,并隐藏该div。
    1. 在鼠标开始拖拽前,记录当前拖拽单元格的位置,并在拖拽开始时将其proxy属性div的位置设置到屏幕外不可见的位置。
    1. 在拖拽时,更新proxy属性div的位置为当前鼠标位置,并返回false以取消默认拖拽事件。
    1. 对于目标单元格,将其设置为可放置状态,并在onDragOver和onDragLeave事件中分别对当前可放置单元格进行样式调整。
    1. 在onDrop事件中,获取被拖拽的单元格和目标单元格的field属性,交换这两个单元格对应的column,并重新渲染datagrid,最后再次调用columnMoving方法实现连续拖拽列的功能。
$.extend($.fn.datagrid.methods,{
    columnMoving: function(jq){
        return jq.each(function(){
            var target = this;
            var cells = $(this).datagrid('getPanel').find('div.datagrid-header td[field]');
            cells.draggable({
                revert:true,
                cursor:'pointer',
                edge:5,
                proxy:function(source){
                    var p = $('<div class="tree-node-proxy tree-dnd-no" style="position:absolute;border:1px solid #ff0000"/>').appendTo('body');
                    p.html($(source).text());
                    p.hide();
                    return p;
                },
                onBeforeDrag:function(e){
                    e.data.startLeft = $(this).offset().left;
                    e.data.startTop = $(this).offset().top;
                },
                onStartDrag: function(){
                    $(this).draggable('proxy').css({
                        left:-10000,
                        top:-10000
                    });
                },
                onDrag:function(e){
                    $(this).draggable('proxy').show().css({
                        left:e.pageX+15,
                        top:e.pageY+15
                    });
                    return false;
                }
            }).droppable({
                accept:'td[field]',
                onDragOver:function(e,source){
                    $(source).draggable('proxy').removeClass('tree-dnd-no').addClass('tree-dnd-yes');
                    $(this).css('border-left','1px solid #ff0000');
                },
                onDragLeave:function(e,source){
                    $(source).draggable('proxy').removeClass('tree-dnd-yes').addClass('tree-dnd-no');
                    $(this).css('border-left',0);
                },
                onDrop:function(e,source){
                    $(this).css('border-left',0);
                    var fromField = $(source).attr('field');
                    var toField = $(this).attr('field');
                    setTimeout(function(){
                        swapField(fromField,toField);
                        $(target).datagrid();
                        $(target).datagrid('columnMoving');
                    },0);
                }
            });

            // swap Field to another location
            function swapField(from,to){
                var columns = $(target).datagrid('options').columns;
                var cc = columns[0];
                _swap(from,to);
                function _swap(fromfiled,tofiled){
                    var fromtemp;
                    var totemp;
                    var fromindex = 0;
                    var toindex = 0;
                    for(var i=0; i<cc.length; i++){
                        if (cc[i].field == fromfiled){
                            fromindex = i;
                            fromtemp = cc[i];
                        }
                        if(cc[i].field == tofiled){
                            toindex = i;
                            totemp = cc[i];
                        }
                    }
                    cc.splice(fromindex,1,totemp);
                    cc.splice(toindex,1,fromtemp);
                }
            }
        });
    }
});

总之,该方法可以实现easyui datagrid列实现动态拖拽列的功能,使得用户可以通过拖拽表头单元格的方式更改datagrid的列顺序,从而获得更好的用户体验。

二、回调保存接口改写Datagrid拖动插件

由于上面的方法EasyUI Datagrid我无法拖动后获取当前列columns顺序保存到后端中,于是我进行的回调的方式改下上面方法,以便于能够在 swapField(fromField,toField) 后能够将排序好的列保存到后端以便于下次查询。

以下是使用回调函数的方式实现easyui datagrid列拖拽后将列顺序保存到后端数据库的Spring Boot后台代码示例:

  1. 前端代码:
$.extend($.fn.datagrid.methods,{
    columnMoving: function(jq, callback){
        return jq.each(function(){
            var target = this;
            var cells = $(this).datagrid('getPanel').find('div.datagrid-header td[field]');
            cells.draggable({
                revert:true,
                cursor:'pointer',
                edge:5,
                proxy:function(source){
                    var p = $('<div class="tree-node-proxy tree-dnd-no" style="position:absolute;border:1px solid #ff0000"/>').appendTo('body');
                    p.html($(source).text());
                    p.hide();
                    return p;
                },
                onBeforeDrag:function(e){
                    e.data.startLeft = $(this).offset().left;
                    e.data.startTop = $(this).offset().top;
                },
                onStartDrag: function(){
                    $(this).draggable('proxy').css({
                        left:-10000,
                        top:-10000
                    });
                },
                onDrag:function(e){
                    $(this).draggable('proxy').show().css({
                        left:e.pageX+15,
                        top:e.pageY+15
                    });
                    return false;
                }
            }).droppable({
                accept:'td[field]',
                onDragOver:function(e,source){
                    $(source).draggable('proxy').removeClass('tree-dnd-no').addClass('tree-dnd-yes');
                    $(this).css('border-left','1px solid #ff0000');
                },
                onDragLeave:function(e,source){
                    $(source).draggable('proxy').removeClass('tree-dnd-yes').addClass('tree-dnd-no');
                    $(this).css('border-left',0);
                },
                onDrop:function(e,source){
                    $(this).css('border-left',0);
                    var fromField = $(source).attr('field');
                    var toField = $(this).attr('field');
                    setTimeout(function(){
                        swapField(fromField,toField);
                        callback([fromField,toField]);
                        $(target).datagrid();
                        $(target).datagrid('columnMoving');
                    },0);
                }
            });

            // swap Field to another location
            function swapField(from,to){
                var columns = $(target).datagrid('options').columns;
                var cc = columns[0];
                _swap(from,to);
                function _swap(fromfiled,tofiled){
                    var fromtemp;
                    var totemp;
                    var fromindex = 0;
                    var toindex = 0;
                    for(var i=0; i<cc.length; i++){
                        if (cc[i].field == fromfiled){
                            fromindex = i;
                            fromtemp = cc[i];
                        }
                        if(cc[i].field == tofiled){
                            toindex = i;
                            totemp = cc[i];
                        }
                    }
                    cc.splice(fromindex,1,totemp);
                    cc.splice(toindex,1,fromtemp);
                }
            }
        });
    }
});
  1. 后端代码:
@RestController
public class DataController {

    @Autowired
    private UserService userService;

    /**
     * 获取指定用户的列顺序信息,并返回给前端
     */
    @PostMapping("/getData")
    public List<Map<String, Object>> getData(Principal principal) {
        // 获取当前登录用户的用户名
        String username = principal.getName();

        // 获取用户保存的列顺序信息
        User user = userService.findByUsername(username);
        List<Column> columnsList = user.getColumnsOrder();

        // 组装easyui datagrid需要的表头信息
        List<Map<String, Object>> headerList = new ArrayList<>();
        for (int i = 0; i < columnsList.size(); i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("field", columnsList.get(i).getField());
            map.put("title", columnsList.get(i).getTitle());
            headerList.add(map);
        }

        // 模拟从数据库获取数据
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (int i = 1; i <= 50; i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", i);
            map.put("name", "User " + i);
            map.put("age", i % 20 + 20);
            map.put("gender", i % 2 == 0 ? "Male" : "Female");
            map.put("address", "Address " + i);
            dataList.add(map);
        }

        // 将表头和数据返回给前端
        Map<String, Object> result = new HashMap<>();
        result.put("total", dataList.size());
        result.put("rows", dataList);
        result.put("columns", headerList);
        return Collections.singletonList(result);
    }

    /**
     * 将指定用户的列顺序信息保存到数据库中
     */
    @PostMapping("/saveColumnsOrder")
    public String saveColumnsOrder(@RequestBody List<Column> columnsList, Principal principal) {
        // 获取当前登录用户的用户名
        String username = principal.getName();

        // 将交换后的列信息保存到数据库中
        User user = userService.findByUsername(username);
        user.setColumnsOrder(columnsList);
        userService.save(user);

        return "OK";
    }
}

说明:这里使用了Spring Security获取当前登录用户的信息。在UserService中需要实现findByUsername()和save()方法。使用回调函数的方式也可以很方便地实现easyui datagrid列拖拽后将列顺序保存到Spring Boot后端数据库的功能。

三、代码中调用方式

以下是使用 easyui datagrid 动态拖动列的调用示例代码:

<table id="dg" class="easyui-datagrid" style="width:100%;height:400px">
</table>

<script>
    // 初始化表格
    $('#dg').datagrid({
        url: /getData,
        columns:[[{
            field:'id',title:'ID',width:50
        },{
            field:'name',title:'Name',width:100
        },{
            field:'age',title:'Age',width:50
        },{
            field:'gender',title:'Gender',width:50
        },{
            field:'address',title:'Address',width:150
        }]],
        onLoadSuccess: function(data){
            // 加载数据成功后,动态添加列
            $.ajax({
                type: "POST",
                contentType: "application/json",
                url: "/getColumns",
                success: function(result){
                    if(result.length > 0){
                        var columns = [];
                        // 组装动态列信息
                        for (var i = 0; i < result.length; i++) {
                            columns.push({
                                field: result[i].field,
                                title: result[i].title,
                                width: result[i].width
                            });
                        }
                        // 添加动态列
                        $('#dg').datagrid('addColumns', {
                            columns: [columns]
                        });
                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.error(xhr.responseText);
                }
            });
        }
    }).datagrid('columnMoving',  function(data){
        //.....保存排序后的列到数据库    
    });
</script>

本文我讲述了如何使用 easyui datagrid 动态列来实现表格的列可配置化。具体实现方式是,通过前端发送ajax请求获取指定用户保存的列顺序信息,在easyui datagrid加载数据成功后使用addColumns方法动态添加列,并将后端返回的动态列信息添加到表格中。同时还提供了保存列顺序信息的接口。

这种方式可以让用户自定义显示哪些列及它们的顺序,提高了表格的灵活性和可用性,满足不同用户的需求。但需要注意的是,动态添加列会增加前端渲染的复杂度和性能开销,需要根据实际情况进行权衡和优化。

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!
代办报建

本公司承接江浙沪报建代办施工许可证。
联系人:张经理,18321657689(微信同号)。

喜欢0发布评论

12条评论

  • ibainfo.com 发表于 3周前

    刚看见一个妹子,很漂亮!http://h5x.yy0.com.cn

  • 游客 发表于 2周前

    帖子很有深度!http://www.guangcexing.net/voddetail/qrtVmvw.html

  • 游客 发表于 1周前

    太邪乎了吧?http://www.guangcexing.net/voddetail/sMDpfggXuF.html

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址