Ecology9明细表中添加操作按钮与弹窗功能技术分享
A. 概述
大家好呀,我又来了! 在Ecology9系统中,我们经常会与遇到一些需求,需要在明细表格中添加操作按钮,并通过点击按钮弹出对话框来实现更多功能。这个东西在标准的weaJs中是无法实现的,需要加入原生JS来实现,本文将详细介绍如何通过自定义渲染字段的方式,在明细表中添加"查看"按钮,并实现点击弹出数据表格的功能。
B. 实现逻辑
逻辑不难,简单划分为下面的流程图

核心机制
- 字段代理渲染:利用
WfForm.proxyFieldComp接口将普通文本框字段重写为按钮组件
ecology最低版本要求:KB900190407
此接口仅对单行文本框字段类型生效,即数据库字段类型为varchar
显示效果、事件、字段值交互都可自行控制,通过接口3.3修改的可编辑字段值也会正常入库
此接口传入的组件,产品会传入此字段依赖的相关props,具体可通过React Developer Tools自行抓取,按需调用
proxyFieldComp: function(fieldMark, el, range)
参数说明
| 参数 | 参数类型 | 必须 | 说明 |
| fieldMark | String | 是 | 字段标示,格式 |
| el | React Comp | 是 | 渲染的组件 |
| range | String | 否 | 作用范围,默认全部,(1:只读、2:可编辑、3:必填),组合后逗号分隔 |
样例
WfForm.proxyFieldComp("field111", React.createElement("div",{style:{background:"red"}, children:"子内容"
}));
//字段111在只读、可编辑、必填情况下自定义渲染WfForm.proxyFieldComp("field222_1", "<div>自定义渲染字段</div>", "2,3");
//明细某行字段222再可编辑、必填情况下自定义渲染
- 动态事件绑定:通过行索引实现按钮与对应数据的关联
- DOM动态创建:使用纯JavaScript创建弹窗组件,避免页面刷新
C. 代码详解
1. 初始化与事件注册
let czDt1 = WfForm.convertFieldNameToId("cz", "detail_1"); // 操作字段idjQuery(document).ready(function () {// 初始化加载明细表中已有的操作按钮addButton();// 监听明细表行添加事件WfForm.registerAction(WfForm.ACTION_ADDROW+"1", function(index){addButton();});
});
功能说明:
- 页面加载完成后立即初始化按钮
- 注册明细表行添加事件,确保新增行也具备操作按钮
- 使用
convertFieldNameToId获取字段ID,确保代码可维护性
2. 按钮添加功能
function addButton() {debuggervar rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(",");for (var i = 0; i < rowArr.length; i++) {var rowIndex = rowArr[i];if (rowIndex !== "") {// 使用标准的方法:将字段组件重写成按钮组件WfForm.proxyFieldComp(czDt1 + "_" + rowIndex, "<button onclick='showTable(\"" + rowIndex + "\")' class='search-button'>查看</button>", "1,2,3,4");}}
}
关键参数说明:
czDt1 + "_" + rowIndex:构造字段标识,格式为field${字段ID}_${明细行号}"1,2,3,4":作用范围,表示在只读、可编辑、必填、隐藏状态下都显示按钮
3. 弹窗触发与数据处理
function showTable(rowIndex) {// 示例数据const sampleData = [{姓名: '张三', 年龄: '28', 城市: '北京', 职业: '软件工程师'},{姓名: '李四', 年龄: '32', 城市: '上海', 职业: '产品经理'},{姓名: '王五', 年龄: '25', 城市: '广州', 职业: 'UI设计师'},{姓名: '赵六', 年龄: '30', 城市: '深圳', 职业: '数据分析师'}];createTablePopup("点击的明细表行下标:" + rowIndex , sampleData)
}
数据处理流程:

4. 弹窗组件实现
function createTablePopup(title, data) {// 创建遮罩层const overlay = document.createElement('div');overlay.style.cssText = `position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0,0,0,0.5);display: flex;justify-content: center;align-items: center;z-index: 10000;`;// 创建弹窗容器const popup = document.createElement('div');popup.style.cssText = `background: white;padding: 25px;border-radius: 10px;box-shadow: 0 5px 15px rgba(0,0,0,0.3);width: 80%;max-width: 700px;max-height: 80%;overflow: auto;position: relative;`;// 创建关闭按钮const closeBtn = document.createElement('button');closeBtn.textContent = '×';closeBtn.style.cssText = `position: absolute;top: 15px;right: 20px;background: #e74c3c;border: none;border-radius: 50%;width: 25px;height: 25px;font-size: 18px;cursor: pointer;color: white;display: flex;align-items: center;justify-content: center;`;closeBtn.onclick = function () {document.body.removeChild(overlay);};// 创建标题const titleEl = document.createElement('h2');titleEl.textContent = title;titleEl.style.cssText = `margin-top: 0;color: #2c3e50;border-bottom: 2px solid #E7F3FC;padding-bottom: 10px;`;// 创建表格const table = document.createElement('table');table.style.cssText = `border-collapse: collapse;width: 100%;margin-top: 15px;font-size: 14px;`;// 创建表头const thead = document.createElement('thead');const headerRow = document.createElement('tr');// 获取表头数据const headers = Object.keys(data[0]);headers.forEach(header => {const th = document.createElement('th');th.textContent = header;th.style.cssText = `border: 1px solid #ddd;padding: 12px;background-color: #E7F3FC;color: black;text-align: left;font-size: 12pt;font-family: Microsoft YaHei;color: black;`;headerRow.appendChild(th);});thead.appendChild(headerRow);table.appendChild(thead);// 创建表格主体const tbody = document.createElement('tbody');data.forEach((rowData, index) => {const row = document.createElement('tr');if (index % 2 === 0) {row.style.backgroundColor = '#f9f9f9';}headers.forEach(header => {const td = document.createElement('td');td.textContent = rowData[header];td.style.cssText = `border: 1px solid #ddd;padding: 10px 12px;`;row.appendChild(td);});tbody.appendChild(row);});table.appendChild(tbody);// 组装弹窗popup.appendChild(closeBtn);popup.appendChild(titleEl);popup.appendChild(table);overlay.appendChild(popup);// 添加到页面document.body.appendChild(overlay);// 点击遮罩层关闭overlay.onclick = function (e) {if (e.target === overlay) {document.body.removeChild(overlay);}};
}
D. 实施过程
- 首先在流程明细表中创建一个操作字段

2. 在代码块中贴如E.代码展示中的代码即可

3. 效果展示

E. 代码展示
let czDt1 = WfForm.convertFieldNameToId("cz", "detail_1"); // 操作字段idjQuery(document).ready(function () {// 初始化加载明细表中已有的操作按钮addButton();// 监听明细表行添加事件WfForm.registerAction(WfForm.ACTION_ADDROW+"1", function(index){addButton();});
});function addButton() {debuggervar rowArr = WfForm.getDetailAllRowIndexStr("detail_1").split(",");for (var i = 0; i < rowArr.length; i++) {var rowIndex = rowArr[i];if (rowIndex !== "") {// 使用标准的方法:将字段组件重写成按钮组件WfForm.proxyFieldComp(czDt1 + "_" + rowIndex, "<button onclick='showTable(\"" + rowIndex + "\")' class='search-button'>查看</button>", "1,2,3,4");}}
}function showTable(rowIndex) {// 示例数据const sampleData = [{姓名: '张三', 年龄: '28', 城市: '北京', 职业: '软件工程师'},{姓名: '李四', 年龄: '32', 城市: '上海', 职业: '产品经理'},{姓名: '王五', 年龄: '25', 城市: '广州', 职业: 'UI设计师'},{姓名: '赵六', 年龄: '30', 城市: '深圳', 职业: '数据分析师'}];createTablePopup("点击的明细表行下标:" + rowIndex , sampleData)
}
// 弹窗表格创建函数
function createTablePopup(title, data) {// 创建遮罩层const overlay = document.createElement('div');overlay.style.cssText = `position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0,0,0,0.5);display: flex;justify-content: center;align-items: center;z-index: 10000;`;// 创建弹窗容器const popup = document.createElement('div');popup.style.cssText = `background: white;padding: 25px;border-radius: 10px;box-shadow: 0 5px 15px rgba(0,0,0,0.3);width: 80%;max-width: 700px;max-height: 80%;overflow: auto;position: relative;`;// 创建关闭按钮const closeBtn = document.createElement('button');closeBtn.textContent = '×';closeBtn.style.cssText = `position: absolute;top: 15px;right: 20px;background: #e74c3c;border: none;border-radius: 50%;width: 25px;height: 25px;font-size: 18px;cursor: pointer;color: white;display: flex;align-items: center;justify-content: center;`;closeBtn.onclick = function () {document.body.removeChild(overlay);};// 创建标题const titleEl = document.createElement('h2');titleEl.textContent = title;titleEl.style.cssText = `margin-top: 0;color: #2c3e50;border-bottom: 2px solid #E7F3FC;padding-bottom: 10px;`;// 创建表格const table = document.createElement('table');table.style.cssText = `border-collapse: collapse;width: 100%;margin-top: 15px;font-size: 14px;`;// 创建表头const thead = document.createElement('thead');const headerRow = document.createElement('tr');// 获取表头数据const headers = Object.keys(data[0]);headers.forEach(header => {const th = document.createElement('th');th.textContent = header;th.style.cssText = `border: 1px solid #ddd;padding: 12px;background-color: #E7F3FC;color: black;text-align: left;font-size: 12pt;font-family: Microsoft YaHei;color: black;`;headerRow.appendChild(th);});thead.appendChild(headerRow);table.appendChild(thead);// 创建表格主体const tbody = document.createElement('tbody');data.forEach((rowData, index) => {const row = document.createElement('tr');if (index % 2 === 0) {row.style.backgroundColor = '#f9f9f9';}headers.forEach(header => {const td = document.createElement('td');td.textContent = rowData[header];td.style.cssText = `border: 1px solid #ddd;padding: 10px 12px;`;row.appendChild(td);});tbody.appendChild(row);});table.appendChild(tbody);// 组装弹窗popup.appendChild(closeBtn);popup.appendChild(titleEl);popup.appendChild(table);overlay.appendChild(popup);// 添加到页面document.body.appendChild(overlay);// 点击遮罩层关闭overlay.onclick = function (e) {if (e.target === overlay) {document.body.removeChild(overlay);}};
}
F. 技术要点
1. 字段代理渲染的优势
- 无侵入式修改:不需要修改原始HTML结构
- 状态兼容:支持只读、可编辑、必填等多种字段状态
- 动态更新:自动响应明细表行的增删操作
2. 弹窗设计特点
- 响应式布局:自适应不同屏幕尺寸
- 用户体验:支持点击遮罩层关闭,提供明确的关闭按钮
- 数据可视化:清晰的表格布局,隔行变色提高可读性
3. 样式规范
- 使用Ecology9标准配色(#E7F3FC)
- 符合Microsoft YaHei字体规范
- 保持与系统一致的视觉风格
