jqGrid Free技术咨询:多年度月度分解数据日历的设计处理
基于jqGrid Free的多年度月度资源管理日历解决方案
针对你用jqGrid Free开发资源管理Web应用时遇到的跨年度月度预览问题,我整理了一套实用的解决方案,涵盖数据结构调整、动态列生成、年度切换等核心环节,完美适配年末及年中后期的预览需求,具体如下:
1. 先重构数据结构:支撑多年度存储
首先得调整后端返回的数据格式,每条资源记录必须包含**年度(year)和月度(month)**字段,不能只存月份。这样才能精准区分不同年度的月度数据,为后续的展示和过滤打基础。示例数据格式如下:
[ { id: 1, projectName: "项目A", resourceName: "张三", year: 2024, month: 7, hours: 160 }, { id: 2, projectName: "项目A", resourceName: "张三", year: 2024, month: 8, hours: 120 }, { id: 3, projectName: "项目B", resourceName: "李四", year: 2025, month: 1, hours: 150 } ]
2. 动态生成列:按需展示跨年度月份
放弃固定列的写法,改为根据当前日期和预览需求动态生成月度列,按年度分组展示。比如当前是2024年8月,就自动隐藏2024年1-7月的列,同时展示2024年8-12月和2025年全年的预览列。核心代码示例:
// 获取当前日期信息 const now = new Date(); const currentYear = now.getFullYear(); const currentMonth = now.getMonth() + 1; // 转成1-12的格式 const previewYear = currentYear + 1; // 初始化基础列(项目、资源名称) const columns = [ { name: "projectName", label: "项目名称", width: 150 }, { name: "resourceName", label: "资源名称", width: 120 } ]; // 添加当前年度的有效月份列(从当前月到12月) for (let month = currentMonth; month <= 12; month++) { const colAlias = `${currentYear}-${String(month).padStart(2, '0')}`; columns.push({ name: colAlias, label: `${currentYear}年${month}月`, width: 80, align: "center", formatter: (cellvalue, options, rowData) => { // 匹配当前行对应年度月份的工时数据 const target = rowData.find(item => item.year === currentYear && item.month === month); return target ? target.hours : 0; } }); } // 添加下一年度的全月预览列 for (let month = 1; month <= 12; month++) { const colAlias = `${previewYear}-${String(month).padStart(2, '0')}`; columns.push({ name: colAlias, label: `${previewYear}年${month}月`, width: 80, align: "center", formatter: (cellvalue, options, rowData) => { const target = rowData.find(item => item.year === previewYear && item.month === month); return target ? target.hours : "-"; // 未录入的用占位符标识 } }); } // 初始化jqGrid $("#resourceGrid").jqGrid({ url: "/api/resource-time-data", datatype: "json", colModel: columns, rowNum: 10, rowList: [10,20,30], pager: "#gridPager", viewrecords: true, caption: "多年度资源时间分配管理" });
3. 增加年度切换控件:灵活切换查看不同年度
给页面加一个下拉选择框,让用户可以手动切换查看任意年度的月度数据,切换时重新生成列并刷新表格:
<div style="margin-bottom:10px;"> <label>选择年度:</label> <select id="yearSelector"> <option value="2024">2024年</option> <option value="2025">2025年</option> <option value="2026">2026年</option> </select> </div>
对应的JS逻辑(可以把列生成逻辑封装成函数,方便复用):
// 封装列生成函数 function generateGridColumns(targetYear) { const now = new Date(); const currentYear = now.getFullYear(); const currentMonth = now.getMonth() + 1; const baseColumns = [ { name: "projectName", label: "项目名称", width: 150 }, { name: "resourceName", label: "资源名称", width: 120 } ]; // 生成目标年度的所有月份列,已过去的月份默认隐藏 for (let month = 1; month <= 12; month++) { const isPast = targetYear < currentYear || (targetYear === currentYear && month < currentMonth); const colAlias = `${targetYear}-${String(month).padStart(2, '0')}`; baseColumns.push({ name: colAlias, label: `${targetYear}年${month}月`, width: 80, align: "center", hidden: isPast, // 已过去的月份默认隐藏 formatter: (cellvalue, options, rowData) => { const target = rowData.find(item => item.year === targetYear && item.month === month); return target ? target.hours : (isPast ? 0 : "-"); } }); } return baseColumns; } // 年度切换事件 $("#yearSelector").on("change", function() { const selectedYear = parseInt($(this).val()); const newColumns = generateGridColumns(selectedYear); // 更新jqGrid列模型并刷新 $("#resourceGrid").jqGrid("setColProp", "colModel", newColumns); $("#resourceGrid").trigger("reloadGrid"); });
4. 结合Column Chooser:保留自定义可见性
保留原有的column chooser功能,因为我们在生成列时给已过去的月份设置了hidden: true,用户可以随时通过chooser手动调出历史月份查看,兼顾自动化和灵活性。确保初始化jqGrid时开启column chooser:
$("#resourceGrid").jqGrid("navGrid", "#gridPager", { edit: false, add: false, del: false }, {}, {}, {}, { multipleSearch: true }); $("#resourceGrid").jqGrid("navButtonAdd", "#gridPager", { caption: "", buttonicon: "ui-icon-calculator", title: "选择要显示的列", onClickButton: function () { $(this).jqGrid("columnChooser"); } });
5. 可选优化:按年度分组展示
如果需要更清晰的年度区分,可以启用jqGrid的分组功能,把同一年度的资源数据聚合在一起:
$("#resourceGrid").jqGrid({ // 其他配置不变 grouping: true, groupingView: { groupField: ["year"], groupColumnShow: [false], // 隐藏年度分组列 groupText: ["<b>{0}年度资源数据</b>"], groupCollapse: false, groupOrder: ["asc"] } });
这套方案完全解决了你提到的年末预览下一年度月份、年中后期无法通过column chooser满足需求的问题,同时保持了jqGrid的原生特性,开发成本也比较低。
内容的提问来源于stack exchange,提问作者LuckyRiver
相关产品推荐
相关产品推荐

