博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JqGridView 1.0.0.0发布
阅读量:4633 次
发布时间:2019-06-09

本文共 16746 字,大约阅读时间需要 55 分钟。

前几个月,客户要求显示列表做到列锁定+表头锁定+列组合,但从Extjs到Jquery EasyUi,从Jquery Grid到Telerik等等组件,发现无一符合条件,要么只能用列锁定,要么只能用列组合,当两者结合就不行了。于是只好开始自己琢磨了,然后就有了jqGridView。

设计思路

 

在开始之前,总得理下思路。我CSS不行,JS一般,但是我有思路,先看看下面两个图:

z

从上图中可以看出,毫无疑问的,我们需要将一个列表切成4块——锁定列表头、锁定列数据行、非锁定列表头、非锁定列数据行。如图:

 

其中,锁定列表头、锁定列数据列、非锁定列表头均无滚动条,滚动条全在非锁定列数据列,但拖动右侧滚动条,需要联动锁定列数据行,但拖动底部滚动条,需联动非锁定列表头。

在我认为,磨刀不误砍柴工。好的想法、好的设计才能更大可能性的走向成功。

接下来,是细节的实现了:

选择什么编程语言呢?好像还没写过Jquery插件,那么就用这个来练练手吧。我对开发新东西或者实现自己的想法或者有兴趣却不熟悉的编码特别来劲。

选择什么方式呢?开始,毫无意外的想到使用Table来组合,于是坑次坑次的开始了。当编码完成后,发现一个棘手的问题——模块之间无法对齐。即使设置了每个单元格宽度以及表格宽度也不行,请了美工辅助也不行,于是放弃了。有意向的朋友可以试试。table不行,那就试试Div吧,人总不能在一条路上走死吧。于是又坑次坑次的开始了,终于修改N次后完成了。

样例

首先举几个例子来说明如何使用:

简单单行表头

合并列

行点击事件

 

 

样式

既然决定使用div,那么样式少不了。我倾向于外观方面的控制全放在样式里面,于是定义了以下样式:

jqGridView样式/*jqGridView Style */.gv-dataContent{	width: 750px;	height: 320px;	margin: 5px auto;	text-align:left;}.gv-dataContent th, tr{	white-space: nowrap;}.gv-dataContent td, th{	padding: 0 0 0 0;	margin: 0 0 0 0;	white-space: nowrap;}.gv-header-left{	width: auto;	overflow: hidden;	float: left;	border-left: 1px solid #539ebb;	border-collapse: collapse;}.gv-header-right{	overflow: hidden;	border-collapse: collapse;}.gv-data-left{	width: auto;	overflow: hidden;	float: left;	border-left: 1px solid #539ebb;	border-bottom: 1px solid #539ebb;	border-collapse: collapse;}.gv-data-right{	overflow: scroll;	border-collapse: collapse;}.gv-div-table{	border-collapse: collapse;	width: auto;}.gv-div-tr{	clear: both;	height: 30px;	overflow: hidden;}.gv-div-th, .gv-div-td{	height: 30px;	float: left;	border: 1px solid white;	margin: 0px 0 0 -1px;	text-align: center;	vertical-align: middle;	line-height: 30px;	border-collapse: collapse;	float: left;	color: #3274a4;}.gv-div-th{	background-color: #86A9D2;	font-weight: bold;	border: 1px solid white;}.gv-tr-rowStyle{	background-color: #8ecbe3;}.gv-tr-alternatingRowStyle{	background-color: #d3ebf4;}.gv-tr-hoverRowStyle{	background-color: #6786d6;	cursor:pointer;}/*GridView 样式*/.HeaderStyle{	background-color:#86A9D2;	font-weight:bold;	height:26px;	white-space: nowrap;	text-align:center;	border: 1px solid white;	color: #3274a4;}.RowStyle{	background-color: #8ecbe3;	height:26px;	text-align:center;	white-space: nowrap;	border: 1px solid white;	color: #3274a4;}.AlternatingRowStyle{	background-color: #d3ebf4;	height:26px;	white-space: nowrap;	border: 1px solid white;	color: #3274a4;	text-align: center;}.datacontent{		font-size:12px;	font-family:微软雅黑;	width:740px;    border:1px solid #7C9BBF;     margin:0 auto;	clear: both; 	text-align: center; 		*text-align: center; 	margin-left: 5px;	padding:5px;	width:760px;	overflow:auto;      }

 

从样式中可以看出大体的规则,也是仿照table元素来的。table、tr、th、td等等。其中有几个重要样式要注意了:

  1. .gv-dataContent    整个jqGridView的整体样式
  2. .gv-header-left      左侧表头区域
  3. .gv-header-right    右侧表头区域
  4. .gv-data-left    左侧数据区域
  5. .gv-data-right  右侧数据区域
  6. .gv-div-table   表示一个表格,每个区域均存在
  7. .gv-div-tr    表示行样式
  8. .gv-div-th   表示表头单元格样式
  9. .gv-div-td   表示单元格样式
  10. .gv-tr-rowStyle   表示奇数行样式
  11. .gv-tr-alternatingRowStyle   表示偶数行样式
  12. .gv-tr-hoverRowStyle  表示悬浮行样式

 

编码

先贴上代码:

1: /**
2: * 本插件用于实现GridView的列锁定和表头锁定,以及表头组合
3: * @example  $.jqGridView('<%=gvData.ClientID %>', { lockColumns: 3 });
4: * @param String gridViewClientID GridView的客户端ID
5: * @option Number lockColumns 锁定的列数。如果包含合并表头,请与合并表头的列数一致。
6: * @option String leftGroupCols 左侧合并列的HTML,不设置则默认为单行表头。
7: * @option String rightGroupCols 右侧合并列的HTML,不设置则默认为单行表头。
8: * @option String removeLeftHeaderStrBySplit 根据分隔符移除左侧头部字符。
9: * @option String removeRightHeaderStrBySplit 根据分隔符移除右侧头部字符。
10: * @option String rowStyle 偶数行样式。
11: * @option String alternatingRowStyle 奇数行样式。
12: * @option String hoverRowStyle 悬浮行样式。
13: * @option Bool isRemoveEmptyAndZeroCols 是否移除空列或者0列。
14: * @option Bool isHideGridView 是否在处理后隐藏GridView。
15: * @option Bool isRemoveGridView 是否在处理后移除GridView。
16: * @option String emptyMessage 没有数据时显示的内容,默认为“没有数据。”。
17: * @option event rowClick 行单击事件。
18: * @author 雪雁
19: * @email codelove1314@foxmail.com
20: * @webSite http://www.cnblogs.com/codelove/
21: */
22: jQuery.jqGridView = function (gridViewClientID, options) {
23:     if (gridViewClientID !== undefined && options !== undefined) {
24:         function formatHeaderHtml(html) {
25:             return html.replace(/\<\/tr>/g, '')
26:             .replace(/\<\/th>/g, '')
27:             .replace(/\<\/td>/g, '');
28:         }
29:         //锁定的列数
30:         var lockColumns = options.lockColumns === undefined ? 1 : options.lockColumns;
31:         //左侧组合列HTML
32:         var leftGroupCols = $(options.leftGroupCols === undefined ? '' : formatHeaderHtml(options.leftGroupCols));
33:         //右侧组合列HTML
34:         var rightGroupCols = $(options.rightGroupCols === undefined ? '' : formatHeaderHtml(options.rightGroupCols));
35:         //根据分隔符移除左侧头部字符
36:         var removeLeftHeaderStrBySplit = options.removeLeftHeaderStrBySplit === undefined ? '' : options.removeLeftHeaderStrBySplit;
37:         var removeRightHeaderStrBySplit = options.removeRightHeaderStrBySplit === undefined ? '' : options.removeRightHeaderStrBySplit;
38:         //偶数行样式
39:         var rowStyle = options.rowStyle === undefined ? '' : options.rowStyle;
40:         //奇数行样式
41:         var alternatingRowStyle = options.alternatingRowStyle === undefined ? '' : options.alternatingRowStyle;
42:         //鼠标悬浮行样式
43:         var hoverRowStyle = options.hoverRowStyle === undefined ? '' : options.hoverRowStyle;
44:         var isSafari = $.browser.safari;
45:         //数据空显示内容
46:         var emptyMessage = options.emptyMessage === undefined ? '没有数据。' : options.emptyMessage;
47:         var gvData = $('#' + gridViewClientID);
48:         if (!gvData || gvData.length == 0) {
49:             console.error("GridView不存在,请检查!!!", gridViewClientID, options);
50:             return;
51:         }
52:         //是否移除空列或者0列
53:         if (options.isRemoveEmptyAndZeroCols !== undefined && options.isRemoveEmptyAndZeroCols) {
54:             var arr_remove = new Array(gvData.find('tr:eq(0) th').length);
55:             var rowsCount = gvData.find('tr:gt(0)').each(function (rIndex) {
56:                 var tr = $(this);
57:                 tr.find('td').each(function (cIndex) {
58:                     if (arr_remove[cIndex] === undefined || arr_remove[cIndex] == null)
59:                         arr_remove[cIndex] = 0;
60:                     var val = $(this).text().replace(/(^\s*)|(\s*$)/g, "");
61:                     if (val == '' || val == 0) {
62:                         arr_remove[cIndex]++;
63:                     }
64:                 });
65:             }).length;
66:             gvData.find('tr').each(function (rIndex) {
67:                 var tr = $(this);
68:                 tr.find('td,th').each(function (cIndex) {
69:                     if (arr_remove[cIndex] == rowsCount)
70:                         $(this).remove();
71:                 });
72:             });
73:         }
74:         var leftCols = lockColumns - 1;
75:         var rightCols = lockColumns;
76:         var isRemoveGridView = options.isRemoveGridView === undefined ? true : options.isRemoveGridView;
77:         //所有列宽
78:         var colsLengsArr = new Array();
79:         var colsCount = gvData.find('tr:eq(0) th').each(function (i) {
80:             colsLengsArr[i] = ($(this).outerWidth() + 1);
81:         }).length;
82:         if (lockColumns >= colsCount) lockColumns = colsCount;
83:         //左侧table宽度
84:         var leftTableWidth = 1;
85:         //右侧table宽度
86:         var rightTableWidth = 1;
87:         for (var i = 0; i < lockColumns; i++) {
88:             leftTableWidth += (colsLengsArr[i] + 1);
89:             if (isSafari) leftTableWidth += 0.3;
90:         }
91:         for (var i = lockColumns; i < colsLengsArr.length; i++) {
92:             rightTableWidth += (colsLengsArr[i] + 1);
93:             if (isSafari) rightTableWidth += 0.3;
94:         }
95: 
96:         gvData.parent().prepend('
');
97:         var gv_dataContent = $('.gv-dataContent');
98:         if (gvData.find('tr').length <= 1) {
99:             gv_dataContent.prepend('
' + emptyMessage + '
');
100:             return;
101:         }
102:         //右侧区域宽度
103:         var rightAreaWidth = gv_dataContent.width() - (leftTableWidth + 25);
104:         //数据区域高度
105:         var dataAreaHeight = gv_dataContent.height();
106: 
107:         gv_dataContent.prepend('
');
108:         var gv_header_left = gv_dataContent.find('div.gv-header-left');
109:         var gv_header_right = gv_dataContent.find('div.gv-header-right');
110:         var gv_data_left = gv_dataContent.find('div.gv-data-left');
111:         var gv_data_right = gv_dataContent.find('div.gv-data-right');
112:         if (lockColumns == colsCount) {
113:             gv_header_right.hide(); gv_data_right.hide();
114:         } else {
115:             if (rightAreaWidth > 0) {
116:                 gv_header_right.width(rightAreaWidth);
117:                 gv_data_right.width(rightAreaWidth + 18);
118:             }
119:         }
120:         var gvData_header_left = gvData.clone();
121:         gvData_header_left.find('tr:gt(0)').remove();
122: 
123:         var gvData_header_right = gvData_header_left.clone();
124:         gv_header_right.find('tr th').remove();
125: 
126:         gv_data_right.find('tr:eq(0)').prepend(gvData_header_left.find('th:gt(' + lockColumns + ')').clone());
127:         gvData_header_right.find('th:lt(' + rightCols + ')').remove();
128:         gvData_header_left.find('th:gt(' + leftCols + ')').remove();
129:         var colIndex = 0;
130: 
131:         function setThs(jqTr, jqHeader, isLeft) {
132:             //            var trHtml = '
';
133:             var trHtml = '
';
134:             jqTr.find('th').each(function (j) {
135:                 trHtml += '
';
136:                 if (removeLeftHeaderStrBySplit != '') {
137:                     var splitStrs = $(this).text().split(removeLeftHeaderStrBySplit);
138:                     trHtml += splitStrs.length > 1 ? splitStrs[1] : splitStrs[0];
139:                 } else if (removeRightHeaderStrBySplit != '') {
140:                     var splitStrs = $(this).text().split(removeRightHeaderStrBySplit);
141:                     trHtml += splitStrs[0];
142:                 }
143:                 else
144:                     trHtml += $(this).html();
145:                 trHtml += '';
146:                 colIndex++;
147:             });
148:             trHtml += '';
149:             jqHeader.prepend(trHtml);
150:         }
151: 
152:         //设置左侧头部HTML
153:         setThs(gvData_header_left, gv_header_left, true);
154:         //设置右侧头部HTML
155:         setThs(gvData_header_right, gv_header_right, false);
156:         //        var gvData_Data_left = $('
');
157:         var gvData_Data_left = $('
');
158:         var gvData_Data_right = $('
');
159:         gvData.find("tr:gt(0)").each(function (i) {
160:             var tr = $(this);
161:             var trLeft = tr.clone();
162:             var trRight = tr.clone();
163:             trLeft.find('td:gt(' + leftCols + ')').remove();
164:             trRight.find('td:lt(' + rightCols + ')').remove();
165:             colIndex = 0;
166:             function setTrTds(tr_left, gvData_Data_left, tr_right, gvData_Data_right, trInfo) {
167:                 var trLeftHtml = '
168:                 if (rowStyle != '' && i % 2 == 0)
169:                     trLeftHtml += ' ' + rowStyle;
170:                 else if (alternatingRowStyle != '' && i % 2 == 1)
171:                     trLeftHtml += ' ' + alternatingRowStyle;
172:                 trLeftHtml += '">';
173:                 var trRightHtml = trLeftHtml;
174:                 tr_left.find('td').each(function (j) {
175:                     trLeftHtml += '
' + $(this).html() + '
';
176:                     colIndex++;
177:                 });
178:                 tr_right.find('td').each(function (j) {
179:                     trRightHtml += '
' + $(this).html() + '
';
180:                     colIndex++;
181:                 });
182:                 trLeftHtml += ''; trRightHtml += '';
183:                 var jqLeftTrHrml = $(trLeftHtml); var jqRightTrHrml = $(trRightHtml);
184:                 if (options.rowClick !== undefined) {
185:                     jqLeftTrHrml.bind('click', { tds: trInfo.find('td'), rIndex: i, isLeft: true }, options.rowClick);
186:                     jqRightTrHrml.bind('click', { tds: trInfo.find('td'), rIndex: i, isLeft: false }, options.rowClick);
187:                 }
188:                 if (hoverRowStyle != '') {
189:                     jqLeftTrHrml.hover(function () { jqLeftTrHrml.addClass(hoverRowStyle); jqRightTrHrml.addClass(hoverRowStyle); }, function () { jqLeftTrHrml.removeClass(hoverRowStyle); jqRightTrHrml.removeClass(hoverRowStyle); });
190:                     jqRightTrHrml.hover(function () { jqLeftTrHrml.addClass(hoverRowStyle); jqRightTrHrml.addClass(hoverRowStyle); }, function () { jqLeftTrHrml.removeClass(hoverRowStyle); jqRightTrHrml.removeClass(hoverRowStyle); });
191:                 }
192:                 gvData_Data_left.append(jqLeftTrHrml);
193:                 gvData_Data_right.append(jqRightTrHrml);
194:             }
195:             setTrTds(trLeft, gvData_Data_left, trRight, gvData_Data_right, tr);
196:         });
197:         gv_data_left.prepend(gvData_Data_left);
198:         gv_data_right.prepend(gvData_Data_right);
199:         if (options.isHideGridView !== undefined && options.isHideGridView)
200:             gvData.hide();
201:         if (isRemoveGridView)
202:             gvData.remove();
203:         if (leftGroupCols != '' && rightGroupCols != '') {
204:             dataAreaHeight -= 62;
205:             colIndex = 0;
206:             function calcGroupCol(groupCols) {
207:                 var groupThs = groupCols.find('.gv-div-th');
208:                 groupThs.each(function (i) {
209:                     var col_width = 0;
210:                     if ($(this).attr('colspan') !== undefined) {
211:                         var colSpan = parseInt($(this).attr('colspan'));
212:                         for (var i = 0; i < colSpan; i++) {
213:                             col_width += colsLengsArr[colIndex];
214:                             colIndex++;
215:                         }
216:                         col_width += (colSpan - 1);
217:                     }
218:                     else if ($(this).attr('rowspan') !== undefined) {
219:                         var rowspan = parseInt($(this).attr('rowspan'));
220:                         col_height = rowspan * 30 + (rowspan - 1);
221:                         $(this).height(col_height).css('border-bottom-style', 'none');
222:                         col_width = colsLengsArr[colIndex];
223:                         if (colIndex <= leftCols)
224:                             gv_header_left.find('.gv-div-th').eq(colIndex).html('').css('border-top-style', 'none');
225:                         else if (colIndex >= rightCols)
226:                             gv_header_right.find('.gv-div-th').eq(colIndex - lockColumns).html('').css('border-top-style', 'none');
227:                         colIndex++;
228:                     }
229:                     else {
230:                         col_width = colsLengsArr[colIndex];
231:                         colIndex++;
232:                     }
233:                     $(this).width(col_width);
234:                 });
235:             }
236:             calcGroupCol(leftGroupCols);
237:             calcGroupCol(rightGroupCols);
238: 
239:             gv_header_left.find('.gv-div-table').prepend(leftGroupCols);
240:             gv_header_right.find('.gv-div-table').prepend(rightGroupCols);
241:         }
242:         else
243:             dataAreaHeight -= 31;
244:         if (dataAreaHeight > 0) {
245:             gv_data_left.height(dataAreaHeight - 18);
246:             gv_data_right.height(dataAreaHeight);
247:         }
248:         //设置滚动事件
249:         $('.gv-data-right').scroll(function () {
250:             $('.gv-data-left').scrollTop($(this).scrollTop());
251:             $('.gv-header-right').scrollLeft($(this).scrollLeft());
252:         });
253:     }
254: };

最后

虽然实现了上面的一些功能,但还是有些缺陷让人遗憾:

  1. 本人美工不行,样式上有些瑕疵。
  2. 测试过IE7、IE8、IE9与Chrome浏览器,目前是正常的,但Chrome浏览器可能有不兼容的情况出现。这点需要有时间慢慢解决。
  3. 不能支持超过2行以上的组合表头,不支持行合并。因为整个jqGridView均使用div组合,所以在行合并上是软肋,不知道各位朋友有什么好的方案没。

 

如果您对jqGridView感兴趣,或者有好的解决方案,或者对源码做了一些修正,请通知我。

最后,本人刚开了个拍拍商店,愿意捧场的朋友请点击下,想获取技术支持的或者想捧场的请点击下,这年头,想真心编码不容易啊。

.net技术交流一群:85318032

转载于:https://www.cnblogs.com/codelove/archive/2012/07/29/2613716.html

你可能感兴趣的文章
第一段冲刺_个人总结_5.2
查看>>
Usage and Idioms——Categories
查看>>
一: 建立Vue sampleproject
查看>>
数据结构之shell排序
查看>>
CodeForces 375D Tree and Queries
查看>>
牛客~~打篮球~~~模拟水题
查看>>
LeetCode-198. 打家劫舍
查看>>
5 -- Hibernate的基本用法 --2 1 Hibernate 下载和安装
查看>>
Socket
查看>>
【C#公共帮助类】10年代码,最全的系统帮助类
查看>>
JQuery UI
查看>>
张弛有度
查看>>
【ZJOI2008】树的统计(树链剖分)
查看>>
【NOIP校内模拟】T2 华莱士(环套树)
查看>>
lists,tuples and sets of Python
查看>>
Superset配置hive数据源
查看>>
查询Master下的系统表和系统视图获取数据库的信息和简单的渗透测试
查看>>
GET和POST的区别
查看>>
Sublime Text 3 及Package Control 安装(附上一个3103可用的Key)
查看>>
jvm 性能调优
查看>>