我正在尝试创建基本 datatables.net 和 coldfusion 服务器端示例,但它似乎不起作用

I am trying to create basic datatables.net and coldfusion server side example but it doesnt seem to works

此示例基于此 link
https://datatables.net/forums/discussion/40613/datatable-jquery-server-side-with-adobe-cold-fusion-and-sql-server

我正在使用数据表版本 1.10

在第一页加载时,所有数据已成功加载到#formsTable
但是点击排序搜索分页就不行了

它只是挂在 'processing..'

pageA.cfm(这里只显示脚本部分...)

<script type="text/javascript"> 
   $(document).ready(function(){        
        $('#formsTable').DataTable({
        processing:true,
        serverSide:true,
        ajax:{
           url:'pageB.cfm'
        },  
        columns:[
                {title: "id",data:'id'},
                {title: "Name",data:'name'},
                {title: "Emp.No",data:'empno'},
                {title: "IC",data:'ic'}
            ]

        })
   })
</script>

pageB.cfm(服务器端)

<cfcontent reset="true">

<cfset listColumns = "id,emp_no,emp_name,number_id2" />

<cfset sIndexColumn = "id" />

<cfparam name="draw" default="1" type="integer" />

<cfparam name="start" default="0" type="integer" />

<cfparam name="length" default="10" type="integer" />

<cfparam name="url.sSearch" default="" type="string" />

<cfparam name="url.iSortingCols" default="0" type="integer" />

<!--- query data --->
<cfquery datasource="hrms" name="qFiltered">
    select id,emp_no,emp_name,number_id2 from employee
    <cfif len(trim(url.sSearch))>
        Where
        (
        <cfloop list="#listColumns#" index="thisColumn">
          <cfif thisColumn neq listFirst(listColumns)>
          OR
          </cfif>
          #thisColumn# LIKE <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="%#trim(url.sSearch)#%" />
        </cfloop>
        )
    </cfif>

    <cfif url.iSortingCols gt 0>
    ORDER BY
    <cfloop from="0" to="#url.iSortingCols-1#" index="thisS">
      <cfif thisS is not 0>, </cfif>
        #listGetAt(listColumns,(url["iSortCol_"&thisS]+1))#
      <cfif listFindNoCase("asc,desc",url["sSortDir_"&thisS]) gt 0>
        #url["sSortDir_"&thisS]#
      </cfif>
    </cfloop>
    </cfif>

</cfquery>

<!--- query data count --->
<cfquery dbtype="query" name="qCount">
    SELECT COUNT(#sIndexColumn#) as total
    FROM qFiltered
</cfquery>

<!--- Output --->
{"draw": <cfoutput>#val(draw)#</cfoutput>,
"recordsTotal": <cfoutput>#qCount.total#</cfoutput>,
"recordsFiltered": <cfoutput>#qFiltered.recordCount#</cfoutput>,
"aaData": [
<cfoutput query="qFiltered" startrow="#val(start+1)#" maxrows="#val(length)#">

<cfif currentRow gt (start+1)>,</cfif>
{
"id":#SerializeJSON(qFiltered.currentrow)#,
"name":#SerializeJSON(qFiltered.emp_name)#,
"empno":#SerializeJSON(qFiltered.emp_no)#,
"ic":
<cfif trim(qFiltered.number_id2) neq '[empty string]'>
#SerializeJSON(qFiltered.number_id2)#
<cfelse>
""
</cfif>
}
</cfoutput> ] }

我卡在这里了,pageB.cfm 上好像少了什么?

已编辑: 感谢@user12031119 指出从 pageA.cfm 发送到 pageB.cfm 的参数现在与 v1.10 不同,所以基本上这些参数应该改变 :-

sEcho : 绘制
iDisplayStart : 开始
iDisplayLength:长度
iTotalRecords:记录总数
iTotalDisplayRecords : 记录过滤

通过该更改,我现在可以单击 next/prev 页面(分页),但搜索和排序仍然不起作用

是的,很遗憾,您在 datatables.net 上查看的代码示例是针对遗留数据表的。在数据表 1.10.x 下,您将必须使用 1.10 版在您的 returned json 结构中期望的升级密钥。看起来您已经使用新参数更新了 pageA.cfm,但是您还需要在 pageB.cfm.

中更新服务器端 return 参数

这是升级到 1.10 版的指南https://datatables.net/upgrade/1.10

这是服务器端 1.10 的新参数指南 https://datatables.net/manual/server-side

编辑 1 感谢 James A Mohler

我自己注意到的每个问题编辑 2

显然我错了,当从服务器 returned 时,datatables 只接受一个数组数组。显然它也接受一个结构数组,这有助于简化我的回答。但是,这将需要为 select 语句中的列设置别名以匹配 pageA.cfm 中定义的列定义。话虽如此,这是需要进行的更改。

对 pageB.cfm 的第一个代码修改是为 select 状态表中的列设置别名,以匹配它们在 pageA.cfm 中的定义。

<cfquery datasource="hrms" name="qFiltered">
    select id as id, emp_no as empno, emp_name as name, number_id2 as ic from employee

完成后,将 <cfoutput> 块中的以下内容从 pageB.cfm

更改为
  • sEcho更改为draw
  • iTotalRecords更改为recordsTotal
  • iTotalDisplayRecords更改为recordsFiltered
  • aaData更改为data
  • 使用 serializeJson() 和 "struct" 选项来 return 结构数组,其键值与您在 pageA.cfm 中定义的方式相匹配。如果您使用的是 ACF 而不是 lucee,那么您可能必须将 pageA.cfm 中的列定义更改为大写,因为 ACF 不保留大小写和大写的键名称。

<!--- Output --->
<cfoutput>
{
    "draw": #val(url.sEcho)#,
    "recordsTotal": #qCount.total#,
    "recordsFiltered": #qFiltered.recordCount#,
    "data": #serializeJson(qFiltered, "struct")# 
}
</cfoutput>

好的,现在终于可以用了。

就是这样,基本的 datatables.net coldfusion/lucee 服务器端示例。

数据表版本 1。10.xx

语言Coldfusion/lucee

pageA.cfm(脚本)

<script type="text/javascript"> 
   $(document).ready(function(){        
        $('#formsTable').DataTable({
        processing:true,
        serverSide:true,
        ajax:{
           url:'pageB.cfm',
           type :'post'
        },  
        columns:[
                {title: "id",data:'id'},
                {title: "Name",data:'name'},
                {title: "Emp.No",data:'empno'},
                {title: "IC",data:'ic'}
            ],
        language: {
            infoEmpty: "No records available",
        }

        })
   })
</script>

pageB.cfm

<cfcontent reset="true">
<cfset listColumns = "id,emp_no,emp_name,number_id2" />
<cfset sIndexColumn = "id" />
<cfparam name="draw" default="1" type="integer" />
<cfparam name="start" default="0" type="integer" />
<cfparam name="length" default="10" type="integer" />
<cfparam name="search" default="" type="string" />

<cfif len(form["search[value]"]) gt 0>
    <cfset search=form["search[value]"]>
</cfif>

<!--- Data set after filtering --->
<cfquery datasource="hrms" name="qFiltered">
select id,emp_no,emp_name,number_id2 from employee
<cfif len(trim(search))>
where
    ( 
    <cfloop list="#listColumns#" index="thisColumn">
    <cfif thisColumn neq listFirst(listColumns)> 
    OR 
    </cfif>
    #thisColumn# LIKE <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="%#trim(search)#%" />    
    </cfloop>
    )
</cfif>
<cfif form["order[0][column]"] gt 0>
    ORDER BY 
    <cfif form["order[0][column]"] eq '1'>
    emp_name <cfif form["order[0][dir]"] eq 'desc'>desc</cfif>
    </cfif>
    <cfif form["order[0][column]"] eq '2'>
    emp_no <cfif form["order[0][dir]"] eq 'desc'>desc</cfif>
    </cfif>
    <cfif form["order[0][column]"] eq '3'>
    number_id2 <cfif form["order[0][dir]"] eq 'desc'>desc</cfif>
    </cfif>    
</cfif>
</cfquery>

<!--- Total data set length --->
<cfquery dbtype="query" name="qCount">
SELECT COUNT(#sIndexColumn#) as total
FROM   qFiltered
</cfquery>

<cfif qFiltered.recordcount gt 0>
    <cfset recordsTotal=#qCount.total#>
<cfelse>
    <cfset recordsTotal=0>
</cfif>

<!---
Output
--->

{"draw": <cfoutput>#val(draw)#</cfoutput>,
"recordsTotal": <cfoutput>#recordsTotal#</cfoutput>,
"recordsFiltered": <cfoutput>#qFiltered.recordCount#</cfoutput>,
"data": 
<cfif qFiltered.recordcount gt 0>
[
<cfoutput query="qFiltered" startrow="#val(start+1)#" maxrows="#val(length)#">
    <cfif currentRow gt (start+1)>,</cfif>
    { 
        "id":#SerializeJSON(qFiltered.currentrow)#,
        "name":#SerializeJSON(qFiltered.emp_name)#,
        "empno":#SerializeJSON(qFiltered.emp_no)#,
        "ic":
        <cfif trim(qFiltered.number_id2) neq '[empty string]'>
        #SerializeJSON(qFiltered.number_id2)#
        <cfelse>
        ""
        </cfif>
    }
</cfoutput> ]
<cfelse>
    ""
</cfif>
 }

首先,检查您的 JSON 输出是否有效 (jsonlint.com) 然后,将您的 JSON 输出包装到 cfsavecontent:

<cfsavecontent variable="json">
    <cfoutput>
     your output here
    </cfoutput>
</cfsavecontent>

然后使用此代码 return JSON:

<cfset lastModDate = DateFormat(Now(),'ddd, dd mmm YYYY') & ' ' & TimeFormat(DateConvert('local2Utc', Now()), 'HH:mm:ss') & ' GMT'> 
<cfheader name="Expires" value="#DateAdd('m', -1, Now())#">
<cfheader name="Last-Modified" value="#lastModDate#">
<cfheader name="cache-control" value="must-revalidate">
<cfheader name="Pragma" value="no-cache">
<cfcontent type="text/x-json" />
<cfoutput>#json#</cfoutput>