【layui】table 样式实现合并单元格
版本 :layui -2.4.5
背景:由于不支持合并单元格,故需要自己实现。将项目上自己封装的合并行、合并列的工具忒上来,作为记录。
直接上案例代码
html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="../../libs/layui/layui-2.4.5/dist/css/layui.css">
<script src="../../libs/jquery-easyui-1.8.5/jquery.min.js"></script>
<script src="../../libs/layui/layui-2.4.5/dist/layui.js"></script>
<script src="./js/compoments.js"></script>
<style>
</style>
</head>
<body style="margin: 50px;">
<div>
<table id="table1"></table>
</div>
<script>
layui.use('table', function () {
var table = layui.table;
var $ = layui.jquery;
var tableId = "table1";
// console.log(res);
//合并单元格
table.render({
elem: '#' + tableId
, url: '../assets/table/data4.json' //数据接口
// , data: res
, cols: [
[ //标题栏
, { field: 'unit', title: '单位', width: 100, rowspan: 2, align: "center" } //rowspan即纵向跨越的单元格数
, { field: 'type', title: '型号', width: 100, rowspan: 2, align: "center" }
, { field: 'num', title: '现有人数', width: 100, rowspan: 2, align: "center" }
, { field: 'isManager', title: '管理/人员', colspan: 2, align: "center" } //colspan即横跨的单元格数,这种情况下不用设置field和width
, { field: 'age', title: '年龄', width: 100, rowspan: 2, align: "center" }
, { field: 'degree', title: '文化程度', width: 100, rowspan: 2, align: "center" }
, { field: 'ageLayer', title: '年龄结构', colspan: 5, align: "center" }
, { field: 'degreeLayer', title: '文化层次', colspan: 6, align: "center" }
], [
{ field: 'username', title: '姓名', width: 100, align: "center" }
, { field: 'work', title: '职务', width: 100, align: "center" }
, { field: 'lte50', title: '>=50', width: 80 }
, { field: 'in40', title: '40-49', width: 80 }
, { field: 'in30', title: '30-39', width: 80 }
, { field: 'in20', title: '<=29', width: 80 }
, { field: 'average', title: '平均', width: 80 }
, { field: 'xx', title: '小学', width: 80 }
, { field: 'cz', title: '初中', width: 80 }
, { field: 'gz', title: '高中', width: 80 }
, { field: 'zz', title: '中专', width: 80 }
, { field: 'dz', title: '大专', width: 80 }
, { field: 'bk', title: '本科', width: 80 }
]
]
, parseData: function (res) { //这个函数用于处理 接收数据和规定格式不符合时,可以在这里进行数据转换
res.data.push({
"id": 92, "unit": "总计","degree":" " ,"mergeRows":1
});
res.data.push({
"id": 92, "unit": "比例","degree":" " ,"mergeRows":2
});
res.data.push({
"id": 93, "unit": "备注","degree":" ", "type": "共计59人,其中管理干部4人,工人55人,平均年龄为51.76。" ,"mergeRows":2
});
res.count = res.data.length;
console.log(res);
return {
"code": res.code, //解析接口状态
"msg": res.msg, //解析提示文本
"count": res.count, //解析数据长度
"data": res.data //解析数据列表
};
}
, done: function (res, curr, count) {
//基础数据(不包括最后三行):计算当地机务段内的救援列车分类,这决定垂直合并的行数
// 从 第 0行开始检查,
if (count <= 3) {
return;
}
var rows = res.data;
//获取第一个垂直合并数
//c0(第1列) 合并所有行
JxLayuiUtil.mergeRowsVertically(tableId, 0, 0, count - 4);
//先找到第一列标题
var title00 = JxLayuiUtil.findTitleCell4JQuery(tableId,0,0);
//对第一列 第一行的单元格必须做特殊处理
var cell00= JxLayuiUtil.findDataCell4JQuery(tableId,0,0);
//显示的第1列恰好如图所示(本列需要全部合并),需要加入这个代码,不然合并样式会有问题
var dataKey = title00.attr("data-key");
cell00.attr("data-key",dataKey);
cell00.find("div").removeClass("laytable-cell-undefined").addClass("laytable-cell-"+dataKey);
//这个合并列函数,需要借助每行数据中包含 mergeRows 字段来控制合并的行数,如果没有这个属性,则合并忽略
//c1,c2,c7-c17
JxLayuiUtil.mergeRowsByMergeRows(tableId,[1, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],res.data,count - 3)
//自动检测指定列 的值,如果相同,就合并。(存在bug:如果与合并行混合使用,样式会乱,请规避
JxLayuiUtil.mergeRowsByColName(tableId,6,'degree',res.data,res.data.length-4)
//汇总数据(最后三行)
if (count >= 3) {
//倒数第三行(合并水平方向的 两个单元格(col=3 and col=4))
JxLayuiUtil.mergeRowsHorizontally(tableId, count - 3, 3, 4);
//倒数第二行(合并水平方向的 两个单元格(col=3 and col=4))
JxLayuiUtil.mergeRowsHorizontally(tableId, count - 2, 3, 4);
//倒数第一行(处理col=0,其他全部合并)
JxLayuiUtil.mergeRowsHorizontally(tableId, count - 1, 1);
// //修改最后一行 的合并的tr->td->div{width:1000px}
JxLayuiUtil.findDataCell4JQuery(tableId, count - 1, 1).find("div").css({width: "100%","text-align": "left" });
}
//如果使用前端插件导出 html 为Excel 时,需要将 合并样式时的 隐藏的 html剔除掉,不然不会影响导出效果。
JxLayuiUtil.clearHideCellClassAfterMergeTable();
}
});
});
</script>
</body>
</html>
合并单元格的方法文件: compoments.js:
/**
* @note 可编辑下拉框
* @author jiangxu
*/
class EditableCombobox {
constructor(layuiId, $) {
this.layuiId = layuiId;
this._$ = $;
this.invaildTagNameOfDD = "id_" + this.layuiId + "_dd";
this.invaildTagNameOfOption = "id_" + this.layuiId + "_option";
this.invalidValue_DataKey = "data-" + this.layuiId;
this.defaultValue4InvalidTag = "#"
this.textObj = this._$(this._$("#" + this.layuiId).next()[0].children[0]);
this.selectObj = this._$(this._$("#" + this.layuiId).next()[0].children[1]);
this.defaultValueObj = this._$("#" + this.layuiId + "_default");
this.init();
this.putDefaultValue();
}
/**
* 用于编辑时回填信息
*/
putDefaultValue() {
/**
* 处于编辑界面时,下拉框会被预填入值的。此时需要处理显示【非法值的问题】
* 在页面加载完毕时触发
*/
//获取实际值
if (!this.defaultValueObj) {
return;
}
var value_default = this.defaultValueObj.val();
if (value_default == undefined || value_default == '' || value_default == null) {
return;
}
//如果是已知的值,就忽略;如果不是,需要追加 非法信息
var arrValue = this.getValidValues();
if (arrValue.indexOf(value_default) >= 0) {
return;
}
console.warn(value_default, arrValue);
this._$("#" + this.layuiId).val(value_default);
this.textObj.find('input').val(value_default);
}
init() {
// var inputStr = "";
var that = this;
this.textObj.on('keyup', function (v) {
that.appendInfoTag4InvalidValue();
});
/**
* 对已有的下拉框值 提前绑定 click 事件。
* 如果点击了已有值,则需要提前清楚【非法值】
*/
this.selectObj.find("dd").on('click', function (v) {
//清除预存 非法值
that._$("#" + that.layuiId).data(that.invalidValue_DataKey, "");
//清除非法值的 dom
// console.log($("#"+layuiId).data("jylc-data"));
// console.log($(this).html())
// 删除之前的 非法的option 的dom
if (that._$("#" + that.invaildTagNameOfOption)) {
that._$("#" + that.invaildTagNameOfOption).remove();
that._$("#" + that.invaildTagNameOfDD).remove();
}
});
}
/**
* 获取有效值集合
*/
getValidValues() {
var values = [];
var that = this;
this._$("#" + this.layuiId).find("option").each(function (index) {
// console.log(that._$(this));
var v = that._$(this).attr("value");
if (v != undefined && v != null && v != '') {
values.push(v);
}
})
return values;
}
/**
* 根据【非法值】追加标签信息
*/
appendInfoTag4InvalidValue() {
var inputStr = this.textObj.find('input').val();
this._$("#" + this.layuiId).data(this.invalidValue_DataKey, inputStr);
// 删除之前的 非法的option 的dom
if (this._$("#" + this.invaildTagNameOfOption)) {
this._$("#" + this.invaildTagNameOfOption).remove();
this._$("#" + this.invaildTagNameOfDD).remove();
}
this._$("#" + this.layuiId).append('<option id="' + this.invaildTagNameOfOption + '" value="' + this.defaultValue4InvalidTag + '" selected>' + inputStr + '</option>')
//先移除内部的 class="layui-this"
this.selectObj.find(".layui-this").removeClass("layui-this");
this.selectObj.append('<dd id="' + this.invaildTagNameOfDD + '" class="layui-this" lay-value="' + this.defaultValue4InvalidTag + '" >' + inputStr + '(未定义)</dd>');
this.textObj.val(this.defaultValue4InvalidTag);
}
getValue() {
var name = this._$("#" + this.layuiId).attr('name');
var value = this._$("#" + this.layuiId).val();
if (value == this.defaultValue4InvalidTag) {
value = this._$("#" + this.layuiId).data(this.invalidValue_DataKey);
}
// var formData = {};
// formData[name] = value;
return value;
}
}
/**
* 和 Layui 相关的工具包
*/
var JxLayuiUtil = {
/**
* @dependence layui-table
* @description 获取数据部分的单元格
* @return jquery对象
*/
findDataCell4JQuery: function (tableId, rowIndex, colIndex) {
if (!tableId) {
console.log("tableId is invalid!")
return null;
}
var table = $("div[lay-id='" + tableId + "']");
var tbody = table.find("tbody");
// console.log(tbody.html())
var rows = tbody.find("tr");
var cols = $(rows[rowIndex]).find("td");
return $(cols[colIndex]);
},
/**
* @dependence layui-table
* @description 获取标题部分的单元格
* @return jquery对象
*/
findTitleCell4JQuery: function (tableId, rowIndex, colIndex) {
if (!tableId) {
console.log("tableId is invalid!")
return null;
}
var table = $("div[lay-id='" + tableId + "']");
var tbody = table.find("thead");
// console.log(tbody.html())
var rows = tbody.find("tr");
if (!rows || !rows[rowIndex]) {
return null;
}
var cols = $(rows[rowIndex]).find("th");
return $(cols[colIndex]);
}
,
/**
* @dependence layui-table
* @description 垂直方向上合并单元格
* @param rootColIndex 需要排序的列号(start from 0) or Array[rootColIndex...]
* @param startRowIndex 排序的起始行号(start from 0)
* @param endRowIndex 排序的结尾行号(start from 0)
*/
mergeRowsVertically: function (tableId, rootColIndex, startRowIndex, endRowIndex) {
if (!tableId) {
console.log("tableId is invalid!")
return;
}
var table = $("div[lay-id='" + tableId + "']");
var tbody = table.find("tbody");
// console.log(tbody.html())
var rows = tbody.find("tr");
if (startRowIndex === undefined) {
startRowIndex = 0;
}
if (endRowIndex === undefined) {
endRowIndex = rows.length - 1;
}
if (startRowIndex < 0 || endRowIndex < 0 || startRowIndex >= endRowIndex) {
console.log("error:[rootColIndex<0||startRowIndex<0||endRowIndex<0||startRowIndex>=endRowIndex]")
return;
}
var table = $("div[lay-id='" + tableId + "']");
var tbody = table.find("tbody");
var rows = tbody.find("tr");
// console.log(rows.length)
//
var startRow = $(rows[startRowIndex]).find("td");
if (rootColIndex instanceof Array) {
rootColIndex.forEach(e => {
$(startRow[e]).attr("rowspan", endRowIndex - startRowIndex + 1)
});
} else {
$(startRow[rootColIndex]).attr("rowspan", endRowIndex - startRowIndex + 1)
}
for (var i = startRowIndex + 1; i < rows.length; i++) {
var cols = $(rows[i]).find("td");
if (i > endRowIndex) {
continue;
}
if (rootColIndex instanceof Array) {
rootColIndex.forEach(e => {
// $(cols[e]).css("display", "none");
// $(cols[e]).remove();
this.eatElement2MergeCell($(cols[e]));
});
} else {
//display:none 会影响 Html 导出Excel 功能,故改为 remove
// $(cols[rootColIndex]).css("display", "none");
// $(cols[rootColIndex]).remove();
this.eatElement2MergeCell($(cols[rootColIndex]))
}
}
},
/**
*
* mergeRowsVertically 的改进版
* 通过 每行数据的 mergeRows( or MERGEROWS )属性 来动态识别需要合并的行数
* 需要注意的是:处于同一合并内的不同行的 mergeRows 需要是相同值
* @param tableId
* @param<Array or int> rootColIndexs single or array (列号从 0 开始)
* @param<Array> dataRows 所有的数据行
* @param<int (not required)> rowTotal 总行数 如果不指定,默认从 dataRows 读取
* @dependence dataRows 中每条数据中必须包含 mergeRows 字段
*/
mergeRowsByMergeRows: function (tableId, rootColIndexs, dataRows, rowTotal) {
var invalidArr = dataRows.filter(e => {
var currentMergeRows = e.mergeRows ? e.mergeRows : e["MERGEROWS"];
if (!currentMergeRows) {
return true;
}
return false;
});
if (invalidArr.length > 0) {
console.warn("it don't contains mergeRows property in [dataRows] ")
return;
}
;
var count = rowTotal ? rowTotal : dataRows.length;
var rootColIndexArray = [];
if (typeof rootColIndexs == 'number') {
rootColIndexArray.push(rootColIndexs);
} else {
rootColIndexArray = rootColIndexs
}
for (var i = 0; i < count;) {
var row = dataRows[i];
var currentMergeRows = row.mergeRows ? row.mergeRows : row["MERGEROWS"];
currentMergeRows = parseInt(currentMergeRows);
this.mergeRowsVertically(tableId, rootColIndexArray, i, i + currentMergeRows - 1);
i += currentMergeRows;
}
},
/**
* 在 mergeRowsVertically 的改性版
* @param colIndex 实际 datagrid 中 columns 中的列号,从 0 开始
* 通过已经排好序的数据中的指定列名 来自动计算该列需要合并的行数
* @limit 只支持 单列
*/
mergeRowsByColName: function (tableId, colIndex, colName, dataRows, rowTotal) {
//检查字段是否存在
var invalidArr = dataRows.filter(e => {
var currentMergeRows = e[colName];
if (!currentMergeRows) {
return true;
}
return false;
});
if (invalidArr.length > 0) {
console.warn("the row don't contains [" + colName + "] property in [dataRows] ")
return;
}
/**
* 第一步 需要计算数据中【colName】列 的相同数据的合并行数,即 mergeRows
* @type {number}
*/
var mergeRows = new Map()
dataRows.forEach(r => {
var total = mergeRows.get(r[colName]);
if (!total) {
mergeRows.set(r[colName], 1);
} else {
mergeRows.set(r[colName], ++total);
}
})
var count = rowTotal ? rowTotal : dataRows.length;
for (var i = 0; i < count;) {
var row = dataRows[i];
var currentMergeRows = mergeRows.get(row[colName]);
currentMergeRows = parseInt(currentMergeRows);
this.mergeRowsVertically(tableId, colIndex, i, i + currentMergeRows - 1);
i += currentMergeRows;
}
}
,
/**
* @dependence layui-table
* @description 水平方向上合并单元格
* @param rootColIndex 需要排序的行号(start from 0)
* @param startColIndex 排序的起始列号(start from 0)
* @param endColIndex 排序的结尾列号(start from 0)
*/
mergeRowsHorizontally: function (tableId, rootRowIndex, startColIndex, endColIndex) {
if (!tableId) {
console.warn("tableId is invalid!")
return;
}
var table = $("div[lay-id='" + tableId + "']");
var tbody = table.find("tbody");
// console.log(tbody.html())
var rows = tbody.find("tr");
//随便取第一行
var cols = $(rows[0]).find("td");
if (startColIndex == undefined) {
startColIndex = 0;
}
if (endColIndex === undefined) {
endColIndex = cols.length - 1;
}
if (rootRowIndex < 0 || startColIndex < 0 || endColIndex < 0 || startColIndex >= endColIndex) {
console.warn("error:[rootRowIndex < 0 || startColIndex < 0 || endColIndex < 0 || startColIndex >= endColIndex]")
return;
}
var cols = $(rows[rootRowIndex]).find("td");
$(cols[startColIndex]).attr("colspan", endColIndex - startColIndex + 1)
for (var i = startColIndex + 1; i <= endColIndex; i++) {
// $(cols[i]).css("display", "none");
// $(cols[i]).remove();
this.eatElement2MergeCell($(cols[i]));
}
}
,
/**
* 吃掉元素
* @param jqueryObj
*/
eatElement2MergeCell: function (jqueryObj) {
if (!jqueryObj) {
return;
}
//display:none 会影响 Html 导出Excel 功能,故改为 remove
jqueryObj.empty().addClass("hideCellClass").css("display", "none");
// jqueryObj.remove();
},
/**
* @description 在合并完 table 所有单元格后,需要清除隐藏的元素
* 不然导出时候,会把隐藏的单元格凸显出来
* @note 如果不需要导出,则可忽略
*/
clearHideCellClassAfterMergeTable: function () {
$('.hideCellClass').remove();
},
/**
* 将form表单转换为json格式
* @param formSelector form标签的id
* @returns {string}
*/
clearForm: function (formSelector, hiddenTagSaving, filterList) {
var flag = false;
$('#' + formSelector).find(':input[name]').each(function () {
var tagName = this.tagName.toLowerCase();
var name = $(this).attr('name');
var hidden = $(this).attr('hidden');
// console.log("--",hidden);
if (tagName === 'input' || tagName === 'textarea') {
if (filterList) {
for (let e in filterList) {
if (filterList[e] != name) {
$(this).val("");
}
}
} else {
//将隐藏的值不能剔除
if (hidden && hiddenTagSaving) {
} else {
$(this).val("");
}
}
} else if (tagName === 'select') {
if (filterList) {
for (let e in filterList) {
if (filterList[e] != name) {
$(this).val("");
layui.form.render('select'); // 重新渲染 select 组件
}
}
} else {
$(this).val("");
layui.form.render('select'); // 重新渲染 select 组件
}
}
});
},
/**
* 打开一个窗口
*/
openWindowByUrl: function (layer, url, options) {
/**
* 默认值
* @type {
{area: string[], maxmin: boolean, fix: boolean, id: string, type: number, title: (title|*|string), content}}
*/
var defaultOptions = {
id: 'detailDialog',
type: 2,
title: "数据详情",
share: 0.8,
area: ['1600px', '750px'], //宽高
fix: false, //不固定
maxmin: false,
content: url,
}
//默认值和用户值进行合并
var settings = $.extend({}, defaultOptions, options);
//打开一个 panel
layer.open(settings);
}
,
/**
* @author jiangxu
* 初始化通用下拉框
* @dependence 形如 <select id="cjcode" name="cjcode" ></select>
* @param layer layui
* @param elId 元素id
* @param url 路由
* @param value2Key 名称 对 键值
* @param defaultVal 默认值
*/
initCommonSelect: function (layui, elId, url, value2Key, defaultVal, callback) {
var keyValName = ["TEXT", "VALUE"];
if (value2Key && value2Key.length === 2) {
keyValName = value2Key
}
var ajax = new layui.HussarAjax(url, function (res) {
// console.log(res);
var select = layui.$('#' + elId);
if (res.data) {
select.html('<option value = "">请选择</option>');
$.each(res.data, function (index, item) {
if (defaultVal && item[keyValName[1]].trim() == defaultVal) {
select.append("<option selected value=" + item[keyValName[1]].trim() + ">" + item[keyValName[0]].trim() + "</option>");
// select.attr("disabled", true);
} else {
select.append("<option value=" + item[keyValName[1]].trim() + ">" + item[keyValName[0]].trim() + "</option>");
}
})
} else {
select.append(new Option("暂无数据", ""));
layui.Hussar.error("请求失败!");
}
layui.form.render("select");
//触发回调
if (callback) {
callback();
}
}, function (data) {
layui.Hussar.error("请求失败!");
});
ajax.async = false;
ajax.realStart();
}
}
/**
* 常用工具类
* @type {
{a: ToolUtil.a}}
* jquery --> $ 是必须的
*/
var JxToolUtil = {
/**
* 获取当前 YYYYMMDD 格式的 日期
* @param offDays 距离当前时间的天数偏移量
*/
getCurrentDateByYYYYMMDD: function (offDays) {
if (!offDays) {
offDays = 0;
}
// 获取当前日期的年月部分
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() + offDays)
var year = currentDate.getFullYear();
var month = currentDate.getMonth() + 1; // 月份从0开始,需要加1
var day = currentDate.getDate();
// 格式化为"yyyy-mm-dd"的字符串
var formattedDate = year + '-' + (month < 10 ? '0' + month : month)
+ '-' + (day < 10 ? '0' + day : day);
// 将格式化后的字符串设置为日期框的值
return formattedDate
},
/**
* 获取当前 YYYYMMDD 格式的 日期
* @param offDays 距离当前时间的天数偏移量
*/
getDateByYYYYMMDD: function (myDate, offDays) {
// 获取当前日期的年月部分
var currentDate = new Date();
if (myDate) {
currentDate = myDate;
}
if (!offDays) {
offDays = 0;
}
currentDate.setDate(currentDate.getDate() + offDays)
var year = currentDate.getFullYear();
var month = currentDate.getMonth() + 1; // 月份从0开始,需要加1
var day = currentDate.getDate();
// 格式化为"yyyy-mm-dd"的字符串
var formattedDate = year + '-' + (month < 10 ? '0' + month : month)
+ '-' + (day < 10 ? '0' + day : day);
// 将格式化后的字符串设置为日期框的值
return formattedDate
},
/**
* 获取当前 YYYYMMDD 格式的 日期
* @param offDays 距离当前时间的天数偏移量
*/
getCurrentFirtDayOfMonthByYYYYMMDD: function () {
// 获取当前日期的年月部分
var currentDate = new Date();
// currentDate.setDate(currentDate.getDate() + offDays)
var year = currentDate.getFullYear();
var month = currentDate.getMonth() + 1; // 月份从0开始,需要加1
var day = 1;
// 格式化为"yyyy-mm"的字符串
var formattedDate = year + '-' + (month < 10 ? '0' + month : month)
+ '-' + (day < 10 ? '0' + day : day);
// 将格式化后的字符串设置为日期框的值
return formattedDate
},
/**
* 获取当前年月字符串日期
* @returns {string} yyyy-mm
*/
getCurrentDateOfYYYYMM: function (offSet) {
if (!offSet) {
offSet = 0;
}
// 获取当前日期
var currentDate = new Date();
var currentYear = currentDate.getFullYear();
var currentMonth = currentDate.getMonth() + 1; // 月份从0开始,所以加1
// 手动计算新的月份和年份
var newMonth = currentMonth + offSet;
// 处理月份的正负溢出,跨年
while (newMonth <= 0) {
currentYear--; // 年份减1
newMonth += 12; // 月份加12
}
while (newMonth > 12) {
currentYear++; // 年份加1
newMonth -= 12; // 月份减12
}
// 格式化月份
var formattedMonth = newMonth < 10 ? '0' + newMonth : newMonth;
// 返回格式化的"yyyy-mm"字符串
return currentYear + '-' + formattedMonth;
},
/**
* 获取当前时间(YYYYMMDD HHMMSS)
* 适配于 Layui 的日期控件
* @param offset 当前日期的偏差(单位:天)
* @returns {string}
*/
getCurrentDateOfYYYYMMDDHHMMSS: function (offset, type) {
if (!offset) {
offset = 0;
}
// 获取当前日期
var currentDate = new Date();
// 手动计算新的日期
currentDate.setDate(currentDate.getDate() + offset);
// 获取年份、月份、日期
var year = currentDate.getFullYear();
var month = currentDate.getMonth() + 1; // 月份从0开始,需要加1
var day = currentDate.getDate();
// 格式化"yyyy-mm-dd"
var formattedDate = year + '-' + (month < 10 ? '0' + month : month)
+ '-' + (day < 10 ? '0' + day : day);
// 获取小时、分钟、秒钟
var h = (currentDate.getHours() < 10 ? "0" + currentDate.getHours() : currentDate.getHours()) + ":";
var m = (currentDate.getMinutes() < 10 ? "0" + currentDate.getMinutes() : currentDate.getMinutes()) + ":";
var s = (currentDate.getSeconds() < 10 ? "0" + currentDate.getSeconds() : currentDate.getSeconds());
if (type == 'S') { //初始时间
return formattedDate + (" 00:00:00");
} else if (type == 'E') { //终止时间
return formattedDate + (" 23:59:59");
} else {
return formattedDate + (" " + h + m + s);
}
},
/**
* 获取当前的时间范围
* @returns {string}
*/
getCurrentDateRange: function (separator) {
if (!separator) {
separator = " ~ ";
}
return this.getCurrentDateByYYYYMMDD(-7) + separator + this.getCurrentDateByYYYYMMDD();
},
/**
* 将form表单转换为json格式
* @param formId form标签的id
* @param mergeNames 合并name 例:['age'], 作用,会自动将重复的age进行递增 后缀会+1,提交到后台就是age=xx,age1=xx,age2=xx
// * @param ts 特殊输入框获取值,自己第三方使用的输入框,自己塞数据到这里即可 ,这是数组 [{name:xx,value:'xx'}]
* @returns {string}
*/
serializeFormToJson: function (formId, mergeNames) {
var formObject = formId;
if (typeof formId == 'string') {
formObject = $('#' + formId);
}
mergeNames = mergeNames || []; // 如果未提供 mergeNames,则默认为空数组
var formData = formObject.find(':input[name]').toArray().reduce(function (obj, element) {
var $element = $(element);
var name = $element.attr('name');
var value;
if ($element.is('select')) {
value = $element.find('option:selected').val();
} else if ($element.is(':checkbox, :radio')) {
if ($element.is(':checked')) {
value = $element.val();
} else {
return obj; // 跳过未选中的复选框或单选按钮
}
} else {
value = $element.val();
}
if (obj.hasOwnProperty(name)) {
if (mergeNames.includes(name)) {
// 合并成数组
if (!Array.isArray(obj[name])) {
obj[name] = [obj[name]]; // 将现有值转换为数组
}
obj[name].push(value);
} else {
// name 已存在,但不需要合并,按计数器方式处理
var counter = 1;
while (obj.hasOwnProperty(name + counter)) {
counter++;
}
obj[name + counter] = value;
}
} else {
obj[name] = value;
}
return obj;
}, {});
return formData;
},
/**
* 收集 form 参数 并转为 url 的参数格式
*/
collectFormParam2Url: function (formId) {
var paramObj = this.serializeFormToJson(formId);
return this.collectObjectParam2Url(paramObj);
},
/**
* 收集 form 参数 并转为 url 的参数格式
*/
collectObjectParam2Url: function (paramObj) {
if (!paramObj) {
return "";
}
var paramUrl = "";
for (let key in paramObj) {
paramUrl += ('&' + key + '=' + paramObj[key]);
}
if (paramUrl) {
paramUrl = paramUrl.substring(1);
}
return paramUrl;
},
/**
* 初始化 单位 的下拉框
* @dependence <script src="${ctxPath}/static/js/plugins/xm-select-v1.2.4/dist/xm-select.js"></script>
* @param arrId id 数组,显然支持多个控件同时渲染
* @waringInfo 每个 ID 需要再 html 内存在对应的 <div id="dw" class="xm-select-demo"></div>
*
* 默认使用参数中的 id 作为 name ,进行重写 div 的 name,故原标签的 name 是无效的。
*/
initTreeCombox4DW: function (id, options) {
if (!id) {
return;
}
// var defaultRequestParams = {"type":"zrdw"};
var defaultRequestParams = {};
if (options && options.requestParams) {
defaultRequestParams = $.extend({}, defaultRequestParams, options.requestParams)
}
var p = JxToolUtil.collectObjectParam2Url(defaultRequestParams)
$.ajaxSettings.async = false;
$.get(ydzb_apiPath + "/szjwCommon/treeAqjxBmxx?" + p, function (response) {
var defaultSelectOptions = { initValue: [] };
if (options) {
defaultSelectOptions = $.extend({}, defaultSelectOptions, options)
}
/**
* 控件的手柄
* @type {*[]}
*/
// 初始化单位树
var dwSelect = xmSelect.render({
el: '#' + id,
name: id,
model: { label: { type: 'text' } },
radio: true,
clickClose: true,
filterable: true,
delay: 100,
data: response.data,
tree: {
show: true,
strict: false,
expandedKeys: ['G00232'],
},
// initValue: ['G00232'],
initValue: defaultSelectOptions.initValue,
height: '200px',
});
/**
* 函数回调,返回 控件的手柄
*/
if (options && options.callback) {
options.callback(dwSelect);
}
});
}
,
// /**
// * 打开一个窗口
// * @deprecated
// */
// openWindowByUrl: function (layer, url, options) {
//
// /**
// * 默认值
// * @type {
{area: string[], maxmin: boolean, fix: boolean, id: string, type: number, title: (title|*|string), content}}
// */
// var defaultOptions = {
// id: 'detailDialog',
// type: 2,
// title: "数据详情",
// share: 0.8,
// area: ['1600px', '750px'], //宽高
// fix: false, //不固定
// maxmin: false,
// content: url,
//
// }
// //默认值和用户值进行合并
// var settings = $.extend({}, defaultOptions, options);
//
// //打开一个 panel
// layer.open(settings);
// }
// ,
}