如何实现ColdFusion CFTABLE单元格可编辑?原CFGRID已失效
替换CFGRID为DataTables实现可编辑表格并同步数据库的最佳方案
一、核心实现思路
- 保留原有单选按钮筛选逻辑,通过ColdFusion查询获取对应数据后,输出为标准HTML表格
- 使用DataTables插件渲染表格,搭配其Editor组件实现单元格/行级编辑功能
- 通过AJAX将编辑操作(新增/修改/删除)提交到ColdFusion后端,执行数据库同步
- 重构原有数据库操作代码,使用安全的参数绑定避免SQL注入风险
二、前端改造步骤
1. 引入必要资源
在页面头部引入DataTables和Editor的CSS与JS文件(建议本地部署资源,避免依赖外部服务):
<link rel="stylesheet" type="text/css" href="DataTables/datatables.min.css"/> <link rel="stylesheet" type="text/css" href="DataTables/Editor/css/editor.dataTables.min.css"/> <script type="text/javascript" src="DataTables/datatables.min.js"></script> <script type="text/javascript" src="DataTables/Editor/js/dataTables.editor.min.js"></script>
2. 重构页面结构
保留原有的筛选表单,将CFTABLE替换为标准HTML表格,同时添加隐藏字段存储原始文档编号(用于更新时定位数据):
<CFFORM ACTION="#cgi.SCRIPT_NAME#" METHOD="POST" id="filterForm"> <center> <b><font size="4" face="britannic bold" color="black">选择要查看的文档状态:全部/活跃/非活跃</font></b><br><br> <table> <tr> <td align="center"><font size="4" face="britannic bold" color="black">筛选条件:</font><br></td> </tr> <tr> <td align="left"><input type="Radio" NAME="order" value="All" checked>全部文档<br></td> </tr> <tr> <td align="left"><input type="Radio" NAME="order" value="Active">仅活跃文档<br></td> </tr> <tr> <td align="left"><input type="Radio" NAME="order" value="Non-Active">仅非活跃文档<br></td> </tr> </table> <br><INPUT TYPE="submit" NAME="view" VALUE="查看报表"> </center> </CFFORM> <cfif structKeyExists(form, "view") and form.view is "查看报表"> <table id="documentTable" class="display" style="width:100%"> <thead> <tr> <th>站点</th> <th>分类</th> <th>标签</th> <th>文档编号</th> <th>描述</th> <th>版本号</th> <th>修订日期</th> <th>审核日期</th> <th>管理员</th> <th>活跃状态</th> <th style="display:none">原始文档编号</th> </tr> </thead> <tbody> <cfswitch expression="#form.order#"> <cfcase value="All"> <cfloop query="get_all_docs"> <tr> <td>#SITE#</td> <td>#sections#</td> <td>#TAB#</td> <td>#DOC_NUMBER#</td> <td>#DESCRIPTION#</td> <td>#REV_LEVEL#</td> <td>#dateFormat(REVISION_DATE, 'yyyy-mm-dd')#</td> <td>#dateFormat(REVIEW_DATE, 'yyyy-mm-dd')#</td> <td>#ADMIN#</td> <td>#ACTIVE#</td> <td style="display:none">#DOC_NUMBER#</td> </tr> </cfloop> </cfcase> <cfcase value="Active"> <cfloop query="active_doc"> <tr> <td>#SITE#</td> <td>#sections#</td> <td>#TAB#</td> <td>#DOC_NUMBER#</td> <td>#DESCRIPTION#</td> <td>#REV_LEVEL#</td> <td>#dateFormat(REVISION_DATE, 'yyyy-mm-dd')#</td> <td>#dateFormat(REVIEW_DATE, 'yyyy-mm-dd')#</td> <td>#ADMIN#</td> <td>#ACTIVE#</td> <td style="display:none">#DOC_NUMBER#</td> </tr> </cfloop> </cfcase> <cfcase value="Non-Active"> <cfloop query="inactive_doc"> <tr> <td>#SITE#</td> <td>#sections#</td> <td>#TAB#</td> <td>#DOC_NUMBER#</td> <td>#DESCRIPTION#</td> <td>#REV_LEVEL#</td> <td>#dateFormat(REVISION_DATE, 'yyyy-mm-dd')#</td> <td>#dateFormat(REVIEW_DATE, 'yyyy-mm-dd')#</td> <td>#ADMIN#</td> <td>#ACTIVE#</td> <td style="display:none">#DOC_NUMBER#</td> </tr> </cfloop> </cfcase> </cfswitch> </tbody> </table> </cfif>
3. 初始化DataTables与Editor
在页面底部添加JS代码,初始化表格并配置编辑功能,指定AJAX提交地址:
<script> $(document).ready(function() { // 初始化Editor var editor = new $.fn.dataTable.Editor({ ajax: { url: '#cgi.SCRIPT_NAME#', type: 'POST' }, table: '#documentTable', fields: [ { label: '站点', name: 'site' }, { label: '分类', name: 'sections' }, { label: '标签', name: 'tab' }, { label: '文档编号', name: 'doc_number' }, { label: '描述', name: 'description' }, { label: '版本号', name: 'rev_level' }, { label: '修订日期', name: 'revision_date', type: 'datetime', format: 'YYYY-MM-DD' }, { label: '审核日期', name: 'review_date', type: 'datetime', format: 'YYYY-MM-DD' }, { label: '管理员', name: 'admin' }, { label: '活跃状态', name: 'active' }, { label: '原始文档编号', name: 'original_doc_number', type: 'hidden' } ] }); // 初始化DataTables $('#documentTable').DataTable({ dom: 'Bfrtip', buttons: [ { extend: 'create', editor: editor }, { extend: 'edit', editor: editor }, { extend: 'remove', editor: editor } ], columns: [ { data: 'site' }, { data: 'sections' }, { data: 'tab' }, { data: 'doc_number' }, { data: 'description' }, { data: 'rev_level' }, { data: 'revision_date' }, { data: 'review_date' }, { data: 'admin' }, { data: 'active' }, { data: 'original_doc_number', visible: false } ] }); }); </script>
三、后端ColdFusion代码改造
1. 处理Editor的AJAX请求
替换原有CFGRID更新逻辑,新增处理Editor提交的代码,使用<cfqueryparam>防止SQL注入:
<!--- 处理DataTables Editor的增删改请求 ---> <cfif structKeyExists(form, "action")> <cfset action = form.action> <cfset data = deserializeJSON(form.data)> <cfswitch expression="#action#"> <cfcase value="create"> <!--- 新增文档 ---> <cfloop item="key" collection="#data#"> <cfquery name="query_insert" datasource="DBSTORE"> INSERT INTO MDL_MASTER_LIST (active, admin, description, doc_number, review_date, revision_date, rev_level, sections, site, tab) VALUES ( <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].active#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].admin#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].description#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].doc_number#">, <cfqueryparam cfsqltype="cf_sql_date" value="#data[key].review_date#">, <cfqueryparam cfsqltype="cf_sql_date" value="#data[key].revision_date#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].rev_level#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].sections#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].site#">, <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].tab#"> ) </cfquery> </cfloop> <!--- 返回成功响应 ---> <cfoutput>#serializeJSON({data = []})#</cfoutput> </cfcase> <cfcase value="edit"> <!--- 修改文档 ---> <cfloop item="key" collection="#data#"> <cfquery name="query_update" datasource="DBSTORE"> UPDATE MDL_MASTER_LIST SET active = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].active#">, admin = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].admin#">, description = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].description#">, doc_number = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].doc_number#">, review_date = <cfqueryparam cfsqltype="cf_sql_date" value="#data[key].review_date#">, revision_date = <cfqueryparam cfsqltype="cf_sql_date" value="#data[key].revision_date#">, rev_level = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].rev_level#">, sections = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].sections#">, site = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].site#">, tab = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].tab#"> WHERE doc_number = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].original_doc_number#"> </cfquery> </cfloop> <cfoutput>#serializeJSON({data = []})#</cfoutput> </cfcase> <cfcase value="remove"> <!--- 删除文档 ---> <cfloop item="key" collection="#data#"> <cfquery name="query_delete" datasource="DBSTORE"> DELETE FROM MDL_MASTER_LIST WHERE doc_number = <cfqueryparam cfsqltype="cf_sql_varchar" value="#data[key].original_doc_number#"> </cfquery> </cfloop> <cfoutput>#serializeJSON({data = []})#</cfoutput> </cfcase> </cfswitch> <cfabort> <!--- 处理完AJAX请求后终止页面渲染 ---> </cfif> <!--- 原有筛选逻辑和表格渲染代码保持不变(粘贴前面重构后的表单和表格代码) --->
四、关键注意事项
- SQL注入防护:必须使用
<cfqueryparam>处理所有用户输入,避免直接拼接SQL语句 - 日期格式:确保前端传递的日期格式与数据库兼容,示例中使用
YYYY-MM-DD格式 - 资源部署:将DataTables和Editor的资源文件部署到ColdFusion项目的可访问目录下
- 权限控制:建议添加用户权限验证,防止未授权用户修改数据
内容的提问来源于stack exchange,提问作者Plumbboy77
相关产品推荐
相关产品推荐

