easyui datagrid动态表格合并单元格
一、根据树节点,对应生成动态表格的表头,合并单元格
如图所示:根据这个树,生成对应的表头
生成对应的表头:
再来个复杂点的树:
对应的表格表头:
easyui datagrid对于这种合并的单元格怎么组织数据?
主要在columns:这个数组这里,如果是像上图这种,三层树结构的,columns数组就是三个数组,每个数组里面又是一个数组,第一个数组放第一行的标题,第二个数组放第二行的标题,第三个数组放第三行的标题
根据树节点,组装表头
//生成datagrid所有列,合并的单元格表头 function gcAllColumns(edit,allChangeColumns,change){ rightTreeAllNode = []; allLeafNodes = []; var level = 0; var treeListJson = '${treeList}'; var treeList = JSON.parse(treeListJson); for(var i=0;i<treeList.length;i++){ var one = treeList[i]; rightTreeAllNode.push(one); if(one.is_bottom == 1){//是叶子节点 allLeafNodes.push(one); } level = one.level_num; if(level>maxLevel){ maxLevel = level; } } var rowspan = maxLevel; initColumns = []; if(rule_order.startsWith('SEX')){ initColumns = [ { field : 'action', title : '操作', width : '110', align : 'center', rowspan : rowspan, formatter : function(value, row, index) { var str = ''; str += $.formatString('<a href="javascript:void(0)" class="organization-easyui-linkbutton-del" style="color: grey" data-options="plain:true,iconCls:\'icon-no\'" onclick="deleteFun(\'{0}\');" >删除</a>', index); return str; } },{ width : '50', title : 'id', field : 'id', hidden : true, rowspan : rowspan, sortable : false }, { width : '50', title : '院系', field : 'org_id', hidden : true, rowspan : rowspan, sortable : false } ,{ width : '50', title : '专业', field : 'major_id', hidden : true, rowspan : rowspan, sortable : false } ,{ width : '50', title : '年级', field : 'grade_id', hidden : true, rowspan : rowspan, sortable : false } ,{ width : '50', title : '班级', field : 'class_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : '性别', field : 'sex_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : 'cost_txt', field : 'cost_txt', hidden : true, rowspan : rowspan, sortable : false },{ width : '150', title : '性别', field : 'sex_name', align: 'center', rowspan : rowspan, sortable : false },{ width : '150', title : '院系', field : 'org_name', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } },{ width : '150', title : '专业', field : 'major_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } },{ width : '150', title : '年级', field : 'grade_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } },{ width : '150', title : '班级', field : 'class_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } }]; }else{ initColumns = [ { field : 'action', title : '操作', width : '110', align : 'center', rowspan : rowspan, formatter : function(value, row, index) { var str = ''; str += $.formatString('<a href="javascript:void(0)" class="organization-easyui-linkbutton-del" style="color: grey" data-options="plain:true,iconCls:\'icon-no\'" onclick="deleteFun(\'{0}\');" >删除</a>', index); return str; } },{ width : '50', title : 'id', field : 'id', hidden : true, rowspan : rowspan, sortable : false }, { width : '50', title : '院系', field : 'org_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : '专业', field : 'major_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : '年级', field : 'grade_id', hidden : true, rowspan : rowspan, sortable : false } ,{ width : '50', title : '班级', field : 'class_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : '性别', field : 'sex_id', hidden : true, rowspan : rowspan, sortable : false },{ width : '50', title : 'cost_txt', field : 'cost_txt', hidden : true, rowspan : rowspan, sortable : false },{ width : '150', title : '院系', field : 'org_name', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } } ,{ width : '150', title : '专业', field : 'major_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } } ,{ width : '150', title : '年级', field : 'grade_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } } ,{ width : '150', title : '班级', field : 'class_name', align: 'center', rowspan : rowspan, sortable : false, formatter : function(value, row, index) { if (value != null && value!="") { return $.formatString('<div title="'+value+'" class="easyui-tooltip">'+value+'</div>'); } } },{ width : '150', title : '性别', field : 'sex_name', align: 'center', rowspan : rowspan, sortable : false }]; } initColumns.push({ 'field': '-1', 'title': subject_name, 'width': '100', 'colspan' : allLeafNodes.length, 'rowspan':1 }); initColumns.push({ width : '', title : '合计(元)', field : 'total', align: 'center', rowspan : rowspan, sortable : false }); allColumns.push(initColumns); for(var i=0;i<maxLevel-1;i++){ allChangeColumns.push(new Array()); } for(var i=0;i<rightTreeAllNode.length;i++){ var node = rightTreeAllNode[i]; var isLeaf = node.is_bottom; var myLevel = node.level_num; if(myLevel==1){//根节点,已加入,不再加入 }else{ var leafChildrenNum = myLeafChildren($('#rightTree'),node); if(isLeaf==1){//是叶子节点,判断是否跨行 var myLevel = myLevel; var myRowSpan = 1; if(myLevel<maxLevel){//非最大层级的叶子节点,要跨行 myRowSpan = maxLevel-myLevel+1; } var myChange = allChangeColumns[myLevel-1-1]; myChange.push({ "field": node.name, "title": node.name, "width": '', 'colspan' : leafChildrenNum, 'rowspan':myRowSpan, 'align': 'center', 'editor': { type: 'numberbox', value:0, options: { "required": true, "missingMessage": '请输入0~999999999.99',min:0,max:999999999.99,precision:2,validType:'length[1,12]',filter:filterLength} } }); }else{ var myChange = allChangeColumns[myLevel-1-1]; myChange.push({ "field": node.name, "title": node.name, "width": '', 'align': 'center', 'colspan' : leafChildrenNum, 'rowspan': 1, }); } } } for(var i=0;i<allChangeColumns.length;i++){ allColumns.push(allChangeColumns[i]); } }
获取当前节点,所有子节点中叶子节点数量,这个数量决定当前单元格,所要跨的列数
function myLeafChildren(treeObj,node){ var leafNum = 0; var allChildren = getAllChildren(treeObj,node); for(var i=0;i<allChildren.length;i++){ var one = allChildren[i]; if(one.children==null){//是叶子节点 leafNum++; } } return leafNum==0?1:leafNum; }
二、时间控件,选择日期时做控制,要用 onSelect 事件
$('#startTime').datebox({ onSelect : function(beginDate){ var beginTime = beginDate.getTime(); var endDate = $('#endTime').datebox("getValue") if (endDate!=null&&endDate!="") { var endTime = new Date($('#endTime').datebox("getValue")).getTime(); if (beginTime>endTime) { parent.window.layer.msg("开始日期不能大于截止日期"); $('#startTime').datebox("setValue", ""); } } } }); $('#endTime').datebox({ onSelect : function(endDate){ var endTime = endDate.getTime(); var beginDate = $('#startTime').datebox("getValue"); if (beginDate!=null&&beginDate!="") { var beginTime = new Date($('#startTime').datebox("getValue")).getTime(); if (beginTime>endTime) { parent.window.layer.msg("截止日期不能小于开始日期"); $('#endTime').datebox("setValue", ""); } } } });
三、layer.open弹出窗口中操作,需要confirm提示确认的:用layer.confirm,要使在顶层显示出来,要用top.layer.confirm
top.layer.confirm('费用组成项结构发生变化,是否要删除数据重新录入?', { btn: ['是','否'] //按钮 }, function(sindex){//是 $.post('${path }/plan/payPlan/deleteRuleAndItemCauseTreeChange', { "plan_id":id }, function(result) { window.parent.window.layer.close(index);//关闭 editDetail(subject_name, subject_id, id,viewFlag); top.layer.close(sindex); }, 'JSON'); }, function(sindex){//否 top.layer.close(sindex); window.parent.window.layer.close(index);//关闭 editDetail(subject_name, subject_id, id,viewFlag); });
四、前台JS中生成UUID
function guid() { function S4() { return (((1+Math.random())*0x10000)|0).toString(16).substring(1); } return (S4()+S4()+S4()+S4()+S4()+S4()+S4()+S4()); }
五、从子节点找节点所在的层级
function getLevel(treeObj, node){ //treeObj为tree的dom对象,node为选中的节点 while(node != null){ node = treeObj.tree('getParent', node.target) length++; } var length1 = length; length = 0; //重置层数 return length1; }
六、从根节点找整个棵的总层级
function getLevelByRoot(){ //treeObj为tree的dom对象,node为选中的节点 rightTreeAllNode = []; allLeafNodes = []; var node = $('#rightTree').tree('getRoot'); if (node == null) { return; } rightTreeAllNode.push(node); var allChildren = getAllChildren($('#rightTree'),node); for(var i=0;i<allChildren.length;i++){ var one = allChildren[i]; rightTreeAllNode.push(one); if(one.children==null){//是叶子节点 allLeafNodes.push(one);//横向跨单元格数量 leafNames.push(one.text); } } var level = 0; for(var i=0;i<allLeafNodes.length;i++){ level = parseInt(allLeafNodes[i].treeType); if(level>maxLevel){ maxLevel = level; } } }
七、树的加载及控制操作
function initLeftTree(){
leftTree = $('#leftTree').tree({
url : '${path }/plan/payPlan/detailTree?plan_id='+'${plan_id}',
animate : true,
parentField : 'pid',
panelHeight : 'auto',
checkbox:function (data) {
var id = data.id;
if(id=='-1'||id=='-2'){//是根节点:行政归属,不让显示checkbox,不让选中
return false;
}
return true;
},
cascadeCheck:false,
onlyLeafCheck : false,
lines : false,
dnd :false, //dnd: true 表示允许拖动节点
onBeforeDrop: function (target,source,point) {
//返回false 则不允许放在这个节点
var targetNode = $('#leftTree').tree("getNode",target); //要拖动到的目标节点下
var targetId = targetNode.id;
var sourceId = source.id;
if((sourceId=='-1'||sourceId=='-2')&&(targetId=='-1'||targetId=='-2')){
if(point!='append'){
return true;
}
}
return false;
},
onCheck : function(node) {//点击触发查询
leftMyIdS=[];
leftMyNameS=[];
clcAllTree(node);
console.log(leftMyIdS.toString());
console.log(leftMyNameS.toString());
$('#leftTreeId').val(leftMyIdS.toString());
$('#leftTreeName').val(leftMyNameS.toString());
},
onLoadSuccess:function(node, data){//当加载完,1.折叠所有节点,2.取消选中节点
$('#leftTree').tree('collapseAll');
}
});
}
八、datagrid中添加一行数据,要的几个单元格数据判断,与之前的数据是否重复,不是完全一样叫重复,这几个单元格,每个数据都是,拼接而成的,当几个单元格数据都包含一个一样的数据,才算重复
//判断重复数据 function isExistSelect(row){ var rows = $("#dataGrid").datagrid("getRows");//表格中已存在数据 var org_id = []; if(!isNull(row.org_id)) org_id = row.org_id.split(","); var major_id = []; if(!isNull(row.major_id)) major_id = row.major_id.split(","); var grade_id = []; if(!isNull(row.grade_id)) grade_id = row.grade_id.split(","); var class_id = []; if(!isNull(row.class_id)) class_id = row.class_id.split(","); var sex_id = []; if(!isNull(row.sex_id)) sex_id = row.sex_id.split(","); for(var i=0;i<rows.length;i++){ var oldRow = rows[i]; var old_org_id = []; if(!isNull(oldRow.org_id)) old_org_id = oldRow.org_id.split(","); var old_major_id = []; if(!isNull(oldRow.major_id)) old_major_id = oldRow.major_id.split(","); var old_grade_id = []; if(!isNull(oldRow.grade_id)) old_grade_id = oldRow.grade_id.split(","); var old_class_id = []; if(!isNull(oldRow.class_id)) old_class_id = oldRow.class_id.split(","); var old_sex_id = []; if(!isNull(oldRow.sex_id)) old_sex_id = oldRow.sex_id.split(","); var f1 = array_intersection(org_id,old_org_id); var f2 = array_intersection(major_id,old_major_id); var f3 = array_intersection(grade_id,old_grade_id); var f4 = array_intersection(class_id,old_class_id); var f5 = array_intersection(sex_id,old_sex_id); if(f1.length>0 && f2.length>0 && f3.length>0 && f4.length>0 && f5.length>0){ existIndex = i+1; return true; } } return false; }
九、JS中取两个集合的交集
function array_intersection(a, b) { // 交集 var result = []; if(a.length==0 && b.length==0){//两个空集,算作重复 result.push("null"); return result; } for(var i = 0; i < b.length; i ++) { var temp = b[i]; for(var j = 0; j < a.length; j ++) { if(temp === a[j]) { result.push(temp); break; } } } return array_remove_repeat(result); }
十、JS数组去重
function array_remove_repeat(a) { var r = []; for(var i = 0; i < a.length; i ++) { var flag = true; var temp = a[i]; for(var j = 0; j < r.length; j ++) { if(temp === r[j]) { flag = false; break; } } if(flag) { r.push(temp); } } return r; }
十一、JS判断是否为空
function isNull(str){ if ( str == "" ) return true; if(str == null) return true; var regu = "^[ ]+$"; var re = new RegExp(regu); return re.test(str); }
十二、浮点数相加,精度失真问题
function floatAdd(a,b){ var o1 = toInteger(a); var o2 = toInteger(b); var n1 = o1.num; var n2 = o2.num; var t1 = o1.times; var t2 = o2.times; var max = t1 > t2 ? t1 : t2; var result = null; if (t1 === t2) { // 两个小数位数相同 result = n1 + n2 } else if (t1 > t2) { // o1 小数位 大于 o2 result = n1 + n2 * (t1 / t2) } else { // o1 小数位 小于 o2 result = n1 * (t2 / t1) + n2 } return result / max; }
十三、将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
/*
* 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
* @param floatNum {number} 小数
* @return {object}
* {times:100, num: 314}
*/
function toInteger(floatNum) { var ret = {times: 1, num: 0}; if (isInteger(floatNum)) { ret.num = floatNum; return ret } var strfi = floatNum + ''; var dotPos = strfi.indexOf('.'); var len = strfi.substr(dotPos + 1).length; var times = Math.pow(10, len); var intNum = parseInt(floatNum * times + 0.5, 10); ret.times = times; ret.num = intNum; return ret }
十四、判断obj是否为一个整数
/* * 判断obj是否为一个整数 */ function isInteger(obj) { return Math.floor(obj) === obj }