datagrid动态生成列并动态赋值

  这周接到的任务是动态生成某datagrid的标题,并且要能够根据动态生成的标题来再去数据库中找到相应的值并拼接赋值上去。

项目经理给我的静态页面如下:

左边一列为车型,右边的上面是零件号,下面是固定的,直接循环生成就行,但是数量不一定,需要动态生成。里面的数据是自动加载的。

后台数据库中能够得到的数据大概是这个形式:

这个问题的难点如下:

1.动态生成datagrid的column。

2.将SQL拿出来的数据拼接成前台需要的横行形式,也就是列转行。

先说下解决的思路和方法。

首先是datagrid。

一般datagrid在使用中都是预先定义好column,这个在官方模板里面是有的,在此不赘述。

但是在这里是不可以的。因为零件号并不固定,所以前台无法写死。在此感谢http://blog.csdn.net/yanjunlu/article/details/8017167博主,提供了很好的解决方法。不过他的方法仍然在静态的基础上,所以需要做一点扩展。

 1 function fetchData(msgId) {
 2         //var msgId = GetQueryString("avonMsgId");
 3
 4         //var msgId = 1;
 5         var s = "";
 6         s = "[["; //用来拼接需要的标题字段
 7         s = s + "{ field:‘ACC_NO‘,  title:‘Accessories‘, width:100, rowspan:2, sortable:true, align:‘left‘  },";
 8         $.ajax({
 9             type : ‘POST‘,
10             url : ‘/TCM/aekoDistribute/getDistribute‘, /*远程获取数据地址*/
11             data : {
12                 msgId : msgId,
13             },
14             success : function(response) {
15                 s = s + distributeOne(response); //得到所有需要的标题字段
16                 options = {};
17                 options.queryParams = {
18                     msgId: msgId
19                 };
20                 options.columns = eval(s);
21                 $("#dispatch_accessories_datagrid").datagrid(options);
22                 $("#dispatch_accessories_datagrid").datagrid(‘reload‘);
23             },
24             error : function(response) {
25                 alert("read item error!");
26             }
27         });
28     }
29
30     function distributeOne(response) {
31         var a = "";
32         a = a + "{title : ‘" + response[0] + "‘, colspan: 2}";
33         for (var i =1;i< response.length; i++) {
34             a = a + ",{title: ‘" + response[i] + "‘, colspan: 2 }";
35         }
36         a = a + "],[";
37         a = a + "{field : ‘" + response[0] + "_dept‘, title: ‘person‘, width : 120, sortable : true, align : ‘left‘},{field : ‘" + response[0] + "_num‘, title: ‘number‘, width : 100, sortable : true,    align:‘left‘}";
38         for (var i =1; i<response.length; i++) {
39             a = a + ",{field : ‘" + response[i] + "_dept‘, title: ‘person‘, width : 120, sortable : true, align : ‘left‘},{field : ‘" + response[i] + "_num‘, title: ‘number‘, width : 100, sortable : true,    align:‘left‘}";
40         }
41         a = a + "]]";
42         return a ;
43     }

其实基本原理就是分两步,首先是拼接出字符串形式的column格式,然后在option中赋值给其column属性,再去执行。

这里面的重点是我返回前台的值是

[390, 4J0, 4W0, 420, 7P0, 8F0, 8K0, 8RD, 8R0, 8T0, 9I0, 95B, 2KC, 3ED, 3Y0, 4GD, 4G0, 4G8, 4H0]

这样的list,所以取出来之后拼接就直接按顺序拿就好。而且上面的title生成的时候不要加field,否则会把下面两列的column给挤走,最后整个顺序就乱了。

真正的难点在第二步,也是耗费了我将近一天时间的难点。

第一个挑战在于行转列。你可以选择SQL直接去转,但是我懒得建立临时表,而且觉得麻烦,返回到前台也不知道什么格式。还想过在事务层重新拼接,但是因为返回格式抓不准的原因也放弃了。最终决定就直接把数据库的数据一个接一个在controll拼成list,大不了三个为一组去取就好。

最后返回的格式是这样:

[8K0907503, 390, 1, 4H0907503, 390, 1, 8K0907503, 4J0, 1, 4H0907503, 4J0, 1, 8K0907503, 4W0, 1, 4H0907503, 4W0, 1, 8K0907503, 420, 1, 4H0907503, 420, 1, 8K0907503, 7P0, 1, 4H0907503, 7P0, 1, 8K0907503, 8F0, 1, 4H0907503, 8F0, 1, 8K0907503, 8K0, 1, 4H0907503, 8K0, 1, 8K0907503, 8RD, 1, 4H0907503, 8RD, 1, 8K0907503, 8R0, 1, 4H0907503, 8R0, 1, 8K0907503, 8T0, 1, 4H0907503, 8T0, 1, 8K0907503, 9I0, 1, 4H0907503, 9I0, 1, 8K0907503, 95B, 1, 4H0907503, 95B, 1, 8K0907503, 2KC, 1, 4H0907503, 2KC, 1, 8K0907503, 3ED, 1, 4H0907503, 3ED, 1, 8K0907503, 3Y0, 2, 4H0907503, 3Y0, 2, 8K0907503, 4GD, 1, 4H0907503, 4GD, 1, 8K0907503, 4G0, 1, 4H0907503, 4G0, 1, 8K0907503, 4G8, 1, 4H0907503, 4G8, 1, 8K0907503, 4H0, 1, 4H0907503, 4H0, 1]

可以看出来三个为一组,很平衡。= =||

但是下面我再次尝试去拼接成字符串,就遇到了很多问题。包括逗号啊,转义啊,括号啊,一个不注意都不行。(顺便说一下项目要求的是IE8,所以完全不具备FF强大的自纠错能力,必须严格写对)

还有就是插入问题,当形成诸如

{‘ACC_NO‘ : ‘8K0907503‘,‘390_num‘:‘1‘,},{‘ACC_NO‘ : ‘4H0907503‘,‘390_num‘:‘1‘,}

的代码后,要插入

8K0907503, 4J0, 1,

然后形成

{‘ACC_NO‘ : ‘8K0907503‘,‘390_num‘:‘1‘,‘4J0_num‘:‘1‘,},{‘ACC_NO‘ : ‘4H0907503‘,‘390_num‘:‘1‘,}

这样的形式。看似简单,其实还是需要考虑一段时间。虽然据说js的replace能够用正则,但是我第一不熟正则,第二总是觉得正则容易错,所以最终采用了截取再拼接的方法:

1 var location = a.indexOf(response[b]);
2 var fore = a.substring(0,location);
3 var param = a.substring(location);
4 var c = "";
5 c = c + "\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}";
6 param = param.replace(/}/, c);
7 a = fore + param;

当一切都拼好后,我自以为是的写下了这一句:

1 $("#dispatch_accessories_datagrid").datagrid(‘loadData‘,data);

然后,一片寂静。。。

最后才想起来,这是赋值,不是静态标题,还要转成json data格式。少不了要按照data格式来重新拼接一番,最后的代码如下:

 1     function fillData(msgId) {
 2         var s = "";
 3         $.ajax({
 4             type: ‘POST‘,
 5             url : ‘/TCM/aekoDistribute/haveAccNo‘,
 6             data : {
 7                 msgId:msgId,
 8             },
 9             success : function(response) {
10                 s = s + haveAccNo(response);
11                 data = $.parseJSON(s);
12
13                 $("#dispatch_accessories_datagrid").datagrid(‘loadData‘,data);
14                 $("#dispatch_accessories_datagrid").datagrid(‘reload‘);
15             }
16         })
17     }
18
19     String.prototype.replaceAll = function(s1,s2){
20         return this.replace(new RegExp(s1,"gm"),s2);
21     }
22
23     function haveAccNo(response) {
24         var a = "";
25         a = a + "{\"total\":" + 1 + ", \"rows\":[";
26
27         /* a = a + "{‘ACC_NO‘ : ‘" + response[0] + "‘, ‘" + response[1] + "_num‘ : ‘" + response[2] + "‘,"
28         for (var i = 3; i < response.length; i+3) {
29             for
30             a = a + ",{‘ACC_NO‘ : ‘" + response[i] + "‘, ‘" + response[i+1] + "_num‘ : ‘" + response[i+2] + "‘,}";
31         } */
32         //先把response%3余0的存入一个数组,然后检查是否存在
33         var arr = new Array();
34         arr.push(response[0]);
35         a = a +  "{\"ACC_NO\" : \""+ response[0] + "\",\"" + response[1] + "_num\":\"" + response[2] + "\",}";
36         var b = 3;
37         for (;b < response.length; b = b+3) {
38             if ($.inArray(response[b], arr) == -1){ //数组中不存在
39                 arr.push(response[b]);
40                 a = a + ",{\"ACC_NO\" : \""+ response[b] + "\",\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}";
41             } else  { //数组中存在
42                 var location = a.indexOf(response[b]);
43                 var fore = a.substring(0,location);
44                 var param = a.substring(location);
45                 var c = "";
46                 c = c + "\"" + response[b+1] + "_num\":\"" + response[b+2] + "\",}";
47                 param = param.replace(/}/, c);
48                 a = fore + param;
49             }
50         }
51         a = a.replaceAll(",}", "}");
52         a = a + "]}";
53         return a ;
54     } 

至此全部完成,最终结果如下:

至于person,那是数据问题,不是我的问题:)

现在的方法以后稍微扩展就能够适用于datagrid几乎所有动态生成的方面。

时间: 2024-07-29 20:01:04

datagrid动态生成列并动态赋值的相关文章

WPF Datagrid 动态生成列 并绑定数据

原文:WPF Datagrid 动态生成列 并绑定数据 说的是这里 因为列头是动态加载的 (后台for循环 一会能看到代码) 数据来源于左侧列 左侧列数据源 当然num1 属于临时的dome使用  可以用ObservableCollection集合代表 动态创建属性 WPF 动态生成对象属性 (dynamic) ObservableCollection<NameList> listName = new ObservableCollection<NameList>(); privat

WPF DataGrid动态生成列的单元格背景色绑定

原文:WPF DataGrid动态生成列的单元格背景色绑定 <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.DisplayIndex}" Value="1"> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSour

EasyUI 动态生成列属性

需求:通过Model类属性动态生成DataGrid表格 1.定义ColumnTitle注解类 package com.mrchu.annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 列标题注解类 * * @author MrChu * @version 1.0 * @date

动态生成java、动态编译、动态加载

我曾经见过一个“规则引擎”,是在应用系统web界面直接编写java代码,然后保存后,规则即生效,我一直很是奇怪,这是如何实现的呢?实际这就好像jsp,被中间件动态的编译成java文件,有被动态的编译成class,同时又动态的加载到classloader中.所以,本质上,纯java得规则引擎,是100%可以实现的. 1.动态生成java源代码.这个过程太过简单,直接略过. 2.动态编译. 我看我们自己的规则引擎也有动态编译,就是在生成BOM模型的时候.但是是调用Process执行javac.但这种

wpf 通过为DataGrid所绑定的数据源类型的属性设置Attribute改变DataGrid自动生成列的顺序

环境Win10 VS2019 .Net Framework4.8 在wpf中,如果为一个DataGrid绑定到一个数据源,默认情况下DataGrid会为数据源类型的每个属性生成一个列(Column)对象.但并没有简单的方式用来控制列的生成顺序. DataGrid提供了两个与自动生成列有关的事件,分别是: AutoGeneratingColumn 会在为每个属性创建列时引发,引发时列已经创建完毕,在这个事件中可以: 通过e.Column获取已经创建的列对象,并对其进行修改. 通过将e.Cancel

easylui datagrid 动态生成列

function load(sdate) { $.getJSON("workorder/statistics.do", { sdate : sdate+'-01' }, function(resp) { //获取数据源 var columns = new Array(); //定义列集合 var row = resp.rows[0]; //获取首行数据 //根据首行数据创建columns配置 $.each(row, function(i, v) { if (i != "use

easyui动态生成列

需求:一个id对应多个key value 将id作为标识列 key值作为表头 value作为值显示.数据表可分为两张表 param数据表: 下表一个id对应上表多个key及value 如下图 id_param数据表: 然后将这些对应关系在前端显示成这样(页数及总记录没有显示,但可实现分页功能) 方法思路: 1.获取param的key value 作为 columns当做表头信息 key作为表头的field,value作为表头的title: 2.获取id_param的所有id(不重复的),构成id

EasyUI 动态生成列加分页

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <meta htt

DataGridView绑定DataTable动态生成列 并且将列名中文显示

方法一: DataGridView绑定获取到的DataTable数据,然后根据每一列手动设置列名,如图 方法二: 在写SQL查询语句的时候,直接在select后边的字段上 AS 想要显示的中文名称即可;如图