使用agGrid的社区版实现层级列表显示

news/2025/11/17 16:25:50/文章来源:https://www.cnblogs.com/wuhuisheng/p/19233321

使用agGrid的社区版实现层级列表显示

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>工单管理系统 - 层级展示</title><!-- Bootstrap CSS --><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"><!-- Bootstrap Icons --><link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet"><!-- Ag-Grid --><script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.js"></script><style>body {background-color: #f8f9fa;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}.container-fluid {padding: 20px;}.card {box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);border: 1px solid rgba(0, 0, 0, 0.125);}.card-header {background-color: #f8f9fa;border-bottom: 1px solid rgba(0, 0, 0, 0.125);}#myGrid {height: 600px;width: 100%;}.level-0 { padding-left: 10px; }.level-1 { padding-left: 40px; }.level-2 { padding-left: 70px; }.level-3 { padding-left: 100px; }.expand-button {background: none;border: none;cursor: pointer;width: 20px;height: 20px;margin-right: 5px;font-size: 12px;color: #6c757d;padding: 0;}.expand-button:hover {color: #495057;}.ag-theme-alpine {--ag-header-background-color: #f8f9fa;--ag-odd-row-background-color: #fcfcfc;--ag-header-foreground-color: #495057;--ag-border-color: #dee2e6;}.status-badge {font-size: 0.75rem;}</style>
</head>
<body><div class="container-fluid"><!-- 页面标题和操作区 --><div class="row mb-4"><div class="col-12"><div class="card"><div class="card-header bg-light"><div class="d-flex justify-content-between align-items-center"><div><h1 class="h4 mb-0 text-primary"><i class="bi bi-clipboard-data me-2"></i>工单管理系统</h1></div><div class="btn-group"><button id="expandAll" class="btn btn-success btn-sm" disabled><i class="bi bi-arrows-expand me-1"></i>展开所有</button><button id="collapseAll" class="btn btn-secondary btn-sm" disabled><i class="bi bi-arrows-collapse me-1"></i>折叠所有</button><button id="refresh" class="btn btn-outline-primary btn-sm" disabled><i class="bi bi-arrow-clockwise me-1"></i>刷新</button></div></div></div></div></div></div><!-- 信息提示 --><div class="row mb-3"><div class="col-12"><div class="alert alert-info d-flex align-items-center"><i class="bi bi-info-circle-fill me-2 fs-5"></i><div><strong>工单层级展示</strong> - 显示父子工单关系,支持展开/折叠查看详细层级<span class="badge bg-primary status-badge ms-2">总工单数: <span id="totalCount">0</span></span><span class="badge bg-success status-badge ms-1">主工单: <span id="parentCount">0</span></span><span class="badge bg-warning status-badge ms-1">子工单: <span id="childCount">0</span></span></div></div></div></div><!-- 数据表格 --><div class="row"><div class="col-12"><div class="card"><div class="card-body p-0"><div id="myGrid" class="ag-theme-alpine"></div></div></div></div></div><!-- 使用说明 --><div class="row mt-3"><div class="col-12"><div class="card"><div class="card-body py-2"><small class="text-muted"><i class="bi bi-lightbulb me-1"></i><strong>使用说明:</strong> 点击行前的箭头图标可展开/折叠子工单,父工单以粗体显示,支持排序和筛选功能</small></div></div></div></div></div><!-- Bootstrap JS --><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script><script>// 工单数据 - 基于您提供的示例const workOrderData = [// 主工单和子工单{ id: 'DD202510270025', parentId: null, workOrderName: 'DJ04/500', materialName: 'IMRC阀', materialCode: 'DJ04', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202510270028', parentId: 'DD202510270025', workOrderName: 'DJ04/500-子工单', materialName: '外壳', materialCode: 'DJ04-008', customerDrawing: '', level2: 1, isParent: false },{ id: 'DD202510300014', parentId: null, workOrderName: 'CP_456/20', materialName: '电脑', materialCode: 'CP_456', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202510300015', parentId: 'DD202510300014', workOrderName: 'CP_456/20-子工单', materialName: '键盘', materialCode: 'BCP-455', customerDrawing: '', level2: 1, isParent: false },{ id: 'DD202510270016', parentId: null, workOrderName: 'DJ27C/500', materialName: '进气控制电机', materialCode: 'DJ27C', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202511070007', parentId: null, workOrderName: '水杯1', materialName: '水杯——管', materialCode: 'CP-2025...', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202510270001', parentId: null, workOrderName: 'DJ03A/332', materialName: '低压打气泵', materialCode: 'DJ03A', customerDrawing: '', level2: 0, isParent: true },// 其他工单{ id: 'DD202510300011', parentId: null, workOrderName: 'CP_456/500', materialName: '电脑', materialCode: 'CP_456', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202511070002', parentId: null, workOrderName: 'CP-20251103/10...', materialName: '吸管——管', materialCode: 'BCP-202...', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202511110009', parentId: null, workOrderName: '联想小新CS11-11', materialName: '联想小新14', materialCode: '1-002', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202510270002', parentId: null, workOrderName: 'DJ100B/539', materialName: '电动EGR阀', materialCode: 'DJ100B-E...', customerDrawing: '', level2: 0, isParent: true },{ id: 'DD202510140006', parentId: null, workOrderName: 'DJ04/700-子工单', materialName: '外壳', materialCode: 'DJ04-008', customerDrawing: '', level2: 0, isParent: true }];// 状态管理let expandedState = new Map();let displayData = [];let gridApi = null;// 更新统计信息function updateStatistics() {const totalCount = workOrderData.length;const parentCount = workOrderData.filter(item => item.parentId === null).length;const childCount = workOrderData.filter(item => item.parentId !== null).length;document.getElementById('totalCount').textContent = totalCount;document.getElementById('parentCount').textContent = parentCount;document.getElementById('childCount').textContent = childCount;}// 递归查找完整路径function findFullPath(nodeId, allData, cache = new Map()) {if (cache.has(nodeId)) {return cache.get(nodeId);}const currentNode = allData.find(item => item.id === nodeId);if (!currentNode) {return null;}if (currentNode.parentId === null) {const path = [currentNode.id];cache.set(nodeId, path);return path;}const parentPath = findFullPath(currentNode.parentId, allData, cache);if (parentPath) {const fullPath = [...parentPath, currentNode.id];cache.set(nodeId, fullPath);return fullPath;}const path = [currentNode.id];cache.set(nodeId, path);return path;}// 构建层级数据function buildHierarchyData(data) {const hierarchyData = [];const pathCache = new Map();// 首先添加所有根节点const rootNodes = data.filter(item => item.parentId === null);function addNode(node, depth = 0) {const fullPath = findFullPath(node.id, data, pathCache);const pathKey = fullPath ? fullPath.join('/') : node.id;const isExpanded = expandedState.get(pathKey) !== false;// 添加当前节点hierarchyData.push({...node,_depth: depth,_isFolder: node.isParent || data.some(item => item.parentId === node.id),_path: pathKey,_isExpanded: isExpanded,_hasChildren: data.some(item => item.parentId === node.id)});// 如果节点有子节点且展开状态,添加子节点if (isExpanded && data.some(item => item.parentId === node.id)) {const children = data.filter(item => item.parentId === node.id).sort((a, b) => a.workOrderName.localeCompare(b.workOrderName));children.forEach(child => addNode(child, depth + 1));}}rootNodes.forEach(root => addNode(root));return hierarchyData;}// 切换展开/折叠状态function toggleExpand(path) {const currentState = expandedState.get(path);expandedState.set(path, !currentState);refreshGrid();}// 刷新网格数据function refreshGrid() {if (!gridApi) {console.error('Grid API 未初始化');return;}try {displayData = buildHierarchyData(workOrderData);gridApi.setGridOption('rowData', displayData);console.log('数据刷新成功,显示记录数:', displayData.length);} catch (error) {console.error('刷新数据时出错:', error);}}// 启用按钮function enableButtons() {document.getElementById('expandAll').disabled = false;document.getElementById('collapseAll').disabled = false;document.getElementById('refresh').disabled = false;}// 自定义工单编号单元格渲染器function workOrderIdRenderer(params) {if (!params.data) return '';const data = params.data;const levelClass = `level-${Math.min(data._depth, 3)}`;let expandButton = '';if (data._hasChildren) {const expandIcon = data._isExpanded ? '<i class="bi bi-caret-down-fill"></i>' : '<i class="bi bi-caret-right-fill"></i>';expandButton = `<button class="expand-button" onclick="toggleExpand('${data._path}')">${expandIcon}</button>`;} else {expandButton = '<span style="display: inline-block; width: 20px;"></span>';}const textStyle = data._depth === 0 ? 'font-weight: 600; color: #0d6efd;' : 'font-weight: normal; color: #495057;';const badge = data._depth === 0 ? '<span class="badge bg-primary badge-sm ms-1">主</span>' : '<span class="badge bg-secondary badge-sm ms-1">子</span>';return `<div class="${levelClass}" style="display: flex; align-items: center;">${expandButton}<span style="${textStyle}">${data.id}</span>${badge}</div>`;}// 自定义工单名称单元格渲染器function workOrderNameRenderer(params) {if (!params.data) return params.value;const data = params.data;const textStyle = data._depth === 0 ? 'font-weight: 600; color: #0d6efd;' : 'font-weight: normal; color: #495057;';const icon = data._depth === 0 ? '<i class="bi bi-folder-fill text-warning me-1"></i>' : '<i class="bi bi-file-earmark text-success me-1"></i>';return `<div style="${textStyle}">${icon}${params.value}</div>`;}// 列定义const columnDefs = [{ field: 'id', headerName: '工单编号',cellRenderer: workOrderIdRenderer,minWidth: 220,flex: 1,sortable: true,filter: true},{ field: 'workOrderName', headerName: '工单名称',//cellRenderer: workOrderNameRenderer,minWidth: 200,flex: 1,sortable: true,filter: true},{ field: 'materialName', headerName: '物料名称',minWidth: 150,flex: 1,sortable: true,filter: true},{ field: 'materialCode', headerName: '物料编码',minWidth: 150,flex: 1,sortable: true,filter: true},{ field: 'customerDrawing', headerName: '客户图号',minWidth: 120,flex: 1,sortable: true,filter: true,cellRenderer: (params) => {return params.value || '<span class="text-muted">-</span>';}}];// Grid选项配置const gridOptions = {columnDefs: columnDefs,rowData: [],animateRows: true,// 默认列配置defaultColDef: {resizable: true,sortable: true,filter: true,minWidth: 100},// 行样式getRowStyle: function(params) {if (params.data && params.data._depth === 0) {return { 'background-color': '#f8f9fa','font-weight': '600'};}return { 'background-color': '#ffffff' };},// Grid就绪回调onGridReady: function(params) {console.log('✅ Ag-Grid 初始化完成!');gridApi = params.api;// 启用按钮enableButtons();// 更新统计信息updateStatistics();// 初始加载数据refreshGrid();console.log('✅ 初始数据加载完成');}};// 初始化Grid - 修复 agGrid 引用问题document.addEventListener('DOMContentLoaded', function() {console.log('🚀 开始初始化Ag-Grid...');const gridDiv = document.querySelector('#myGrid');if (!gridDiv) {console.error('❌ 找不到网格容器元素');return;}try {// 检查 agGrid 是否已加载if (typeof agGrid === 'undefined') {console.error('❌ agGrid 未正确加载,请检查 CDN 链接');return;}// 使用正确的初始化方式const gridInstance = new agGrid.createGrid(gridDiv, gridOptions);console.log('✅ Ag-Grid 实例创建成功');} catch (error) {console.error('❌ 创建Ag-Grid实例时出错:', error);// 显示错误信息给用户gridDiv.innerHTML = `<div class="alert alert-danger m-3"><h4 class="alert-heading">初始化失败</h4><p>无法加载表格组件,请检查网络连接或刷新页面重试。</p><hr><p class="mb-0">错误详情: ${error.message}</p></div>`;}// 展开所有按钮document.getElementById('expandAll').addEventListener('click', function() {if (!gridApi) {console.warn('Grid API 尚未就绪');return;}workOrderData.forEach(item => {const fullPath = findFullPath(item.id, workOrderData);const pathKey = fullPath ? fullPath.join('/') : item.id;expandedState.set(pathKey, true);});refreshGrid();console.log('✅ 已展开所有节点');});// 折叠所有按钮document.getElementById('collapseAll').addEventListener('click', function() {if (!gridApi) {console.warn('Grid API 尚未就绪');return;}workOrderData.forEach(item => {const fullPath = findFullPath(item.id, workOrderData);const pathKey = fullPath ? fullPath.join('/') : item.id;expandedState.set(pathKey, false);});refreshGrid();console.log('✅ 已折叠所有节点');});// 刷新数据按钮document.getElementById('refresh').addEventListener('click', function() {refreshGrid();console.log('✅ 数据已刷新');});});// 页面加载完成后显示调试信息window.addEventListener('load', function() {console.log('=== 系统状态 ===');console.log('Grid API:', gridApi ? '已初始化' : '未初始化');console.log('数据总数:', workOrderData.length);console.log('agGrid 对象:', typeof agGrid !== 'undefined' ? '已加载' : '未加载');});</script>
</body>
</html>

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/968072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

case linux

你提到的“case linux”可能是一个表述上的误差或简写。如果你是想询问与 Linux 系统相关的问题,我非常乐意帮助你。请具体说明你感兴趣的内容,例如:Linux 命令行使用 Shell 脚本编写 系统管理(如文件系统、进程管…

2025年在淮安婚纱照拍摄团队公司实力盘点,弥素摄影工作室领衔十大精品机构

定格时光,珍藏爱情,用专业影像诠释独属于你们的浪漫故事。 近年来,淮安婚纱摄影行业迎来了品质升级的浪潮。据淮安市摄影行业协会数据显示,2024年淮安地区婚纱摄影市场规模预计突破亿元,个性化定制需求增长达35%,…

cadence linux

您提到的“Cadence Linux”可能是指与 Cadence 公司相关的 Linux 系统,Cadence 是一家知名的半导体设计公司,其产品包括用于 FPGA、ASIC 和 IC 设计的工具链,如 Cadence Incisive、Cadence Virtuoso 等。 如果您是想…

当下山西比较好的纪念馆展示柜工厂排行榜揭晓

摘要 纪念馆展示柜行业在2025年迎来快速发展,随着文化强国战略的推进,山西地区成为文博设施建设的重要区域。本文基于行业数据和用户口碑,为您呈现山西纪念馆展示柜厂家排名前十的权威榜单,旨在帮助文博单位高效选…

2025年山西博物馆展示柜厂家排名前十推荐:专业评测与选择指南

摘要 随着文博产业的快速发展,博物馆展示柜行业在2025年迎来创新高潮,智能化、定制化成为主流趋势。本文基于权威数据和市场调研,为您呈现山西地区博物馆展示柜厂家排名前十的详细榜单,旨在帮助用户规避选择误区,…

2025年山西博物馆展示柜厂家排名前十权威推荐

摘要 随着文博产业的快速发展,博物馆展示柜作为文物保护和展示的核心载体,行业需求持续增长。2025年,山西地区博物馆展示柜厂家竞争激烈,本文基于技术实力、口碑评价和服务案例,为您呈现排名前十的厂家综合评测。…

2025年四川硬芯线厂家排名前十权威评测及行业选择指南

摘要 硬芯线作为电线电缆行业的核心产品,广泛应用于电力、建筑、新能源和工业自动化等领域。随着2025年新能源和智能电网的快速发展,四川地区硬芯线市场需求持续增长,厂家竞争加剧。本文基于行业数据和技术参数,综…

2025年封闭母线槽厂家综合实力排行榜前十强权威发布

摘要 随着我国电力基础设施建设的快速发展,封闭母线槽行业在2025年迎来新一轮技术革新与市场洗牌。本文基于行业数据调研、技术参数对比和用户口碑反馈,综合评估国内主流封闭母线槽厂家的综合实力,为电力工程企业、…

百度贴吧 电子工程世界 哔哩哔哩 凯迪网 一牛网 电子工程网 思否 知乎 技术邻

VKL060是一个点阵式存储映射的LCD驱动器,可支持最大60点(15SEGx4COM)的 LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据,可配置4种功耗模式,也可通 过关显示和关振荡器进入省电模式。其高抗干扰,低功耗的…

2025年国内锯条品牌口碑推荐排行榜TOP10权威发布

文章摘要 随着制造业的快速发展,2025年国内锯条行业迎来新一轮技术革新与市场洗牌。本文基于行业数据调研、用户口碑评价及技术参数对比,为您呈现本年度最具权威性的锯条品牌排行榜单。榜单综合考量企业技术实力、产…

Codeforces Round 1064 (Div. 2) 做题记录

T1看了这么多 T1,终于找到简单题了!!!发现最后一个点无法更改,要使所有点都相等,也就是让 \(1 \sim n-1\) 的所有点都和 \(n\) 号点相等。 那么修改的次数就是 \(1 \sim n-1\) 中和 \(n\) 号点不同的点的数量。 …

2025年成都中杆灯厂家综合实力TOP10排行榜

摘要 随着城市化进程加速和智慧城市建设深入推进,2025年中杆灯行业迎来新一轮发展机遇。成都作为西南地区核心城市,其中杆灯市场需求持续增长,产品质量和技术创新成为行业竞争关键。本文基于市场调研和行业数据分析…

2025年下半年金属锯床厂家权威排名榜单:五大品牌综合评测

摘要 随着制造业智能化转型加速,2025年金属锯床行业迎来技术升级高峰。本文基于市场调研数据、用户反馈及技术参数,对当前主流金属锯床品牌进行综合排名,为采购商提供参考依据。榜单包含品牌介绍、技术优势及服务对…

2025年11月四川带锯床厂家口碑推荐榜单:成都鸿远机械领跑行业

摘要 2025年四川带锯床行业迎来新一轮技术升级浪潮,智能制造与高效切割成为市场主流需求。成都鸿远机械有限公司凭借其卓越的产品性能和完善的售后服务体系,在本次口碑评选中脱颖而出。本文基于行业数据与用户反馈,…

解密数字设计中的IP核心:高效构建电子系统的关键积木

在当前复杂的数字设计领域,知识产权(Intellectual Property,IP)被广泛用作集成电路(IC)与电子系统的“标准模块”,有效提升了研发效率与创新能力。本文将全面解读数字设计中的IP,从核心概念、类型与优势解读其…

基于MATLAB的DPSK调制解调仿真

基于MATLAB的DPSK调制解调仿真代码,包含差分编码、相干解调、误码率分析和性能可视化模块一、核心仿真代码 %% 参数设置 clear; clc; close all;% 系统参数 N = 10000; % 码元数 fc = 10; % 载波频率…

2025年江苏浙江上海地区留学服务商综合实力排行榜TOP10

摘要 随着中国留学市场的持续升温,2025年留学服务行业呈现专业化、精细化发展趋势。江苏、浙江、上海地区的留学服务机构在服务质量、申请成功率等方面表现突出,成为众多学子的首选。本文基于市场调研数据和用户反馈…

想要寻找催化剂破坏牢固的键 想用相同热量找回最初感觉 麻木重复的过程逐渐取代新鲜 心腐蚀了一遍一遍

test41输出字符串 按照题意模拟即可。 #pragma GCC optimize(1,2,3,"Ofast","inline") #include<bits/stdc++.h> #define int long long #define up(i,l,r) for(int i=l; i<=r; ++i) #de…

2025年单向逆止托辊轴承实力厂家权威推荐榜单:皮带机托辊轴承/防尘防静电轴承/橡胶托辊轴承源头厂家精选

在工业传动领域,优质单向逆止托辊轴承是保障输送系统稳定运行的核心。 单向逆止托辊轴承作为矿山、港口、电力等行业输送设备的关键部件,其性能直接影响到整个生产系统的运行效率与安全性。2025年,随着工业自动化要…

2025年纯铜龙柱订做厂家权威推荐:小型铜龙柱/五代鎏金铜龙柱/锻铜龙柱源头厂家精选

随着城市景观建设和文化场所升级需求的持续增长,纯铜龙柱作为融合传统工艺与现代美学的建筑装饰,市场需求稳步提升。纯铜龙柱凭借其独特的文化价值、艺术表现力以及耐候性,在城市广场、文化园区、宗教场所及高端酒店…