This example was based on this link
https://datatables.net/forums/discussion/40613/datatable-jquery-server-side-with-adobe-cold-fusion-and-sql-server
and i am using datatable version 1.10
On first page load, all data sucessfully loaded into #formsTable
But it wont work when clicking sorting,searching and paging.
It just hang with 'processing..'
pageA.cfm (only show scripting part here...)
<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 (server-side)
<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> ] }
I am stuck here , it seems that something is missing on pageB.cfm ?
Edited:
thanks for #user12031119 pointing out that sent parameter from pageA.cfm to pageB.cfm is different now with v1.10, so basically these parameters should be change :-
sEcho : draw
iDisplayStart : start
iDisplayLength : length
iTotalRecords : recordsTotal
iTotalDisplayRecords : recordsFiltered
with that change i can now click on next/prev page (paging) but still search and sorting dont work
Yes, unfortunately the code sample you're viewing on datatables.net is for legacy datatables. Under datatables 1.10.x, you will have to use the upgraded keys which version 1.10 expects in your returned json structure. It looks like you already updated pageA.cfm with the new parameters, however you also need to update your server-side return parameters in pageB.cfm.
Here's a guide to upgrade to version 1.10 https://datatables.net/upgrade/1.10
Here's a guide for the new parameters for server-side 1.10 https://datatables.net/manual/server-side
Edit 1 thanks to James A Mohler
Edit 2 per issue noticed by myself
Apparently I was mistaken that datatables only accepts an array of arrays when returned from the server. Apparently it also accepts an array of structs, which helps simplify my answer. However, this will require aliasing the columns in the select statement to match the column definitions defined in pageA.cfm. With that said, here are the changes needed.
The first code modification to pageB.cfm will be to alias the columns in your select statemen to match their definition in 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
Once that's done, change the following in your <cfoutput> block from pageB.cfm
Change sEcho to draw
Change iTotalRecords to recordsTotal
Change iTotalDisplayRecords to recordsFiltered
Change aaData to data
Use serializeJson() with the "struct" option to return an array of structs with the key values matching up to how you defined them in pageA.cfm. If you're using ACF instead of lucee, then you might have to change your column definitions in pageA.cfm to uppercase since ACF doesn't preserve case and uppercases key names.
<!--- Output --->
<cfoutput>
{
"draw": #val(url.sEcho)#,
"recordsTotal": #qCount.total#,
"recordsFiltered": #qFiltered.recordCount#,
"data": #serializeJson(qFiltered, "struct")#
}
</cfoutput>
First, check that your JSON output is valid (jsonlint.com)
Then, wrap your JSON output into a cfsavecontent:
<cfsavecontent variable="json">
<cfoutput>
your output here
</cfoutput>
</cfsavecontent>
Then use this code to return the 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>
OK finally it works now.
So this is it, basic datatables.net coldfusion/lucee server side example.
Datatables Version 1.10.xx
Language Coldfusion/lucee
pageA.cfm (scripting)
<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>
}
I have a cfm page with several queries (one cfinvoke in a cfloop from a query). When the page is loading, the loading of data take a long time before to be completely displayed.
Data are displayed in an html table thanks to the cfloop. I saw that the display is progressively displayed.
I would like to know how to improve that with a lazy loading (with a loading message or icon).
my script:
<!-------------------------------- GET DATA ON THE MEETING ----------------------------- START --->
<cftry>
<cfquery name="qry_reunion" datasource="#application.datasource#">
SELECT
R.*
FROM REUNION R
LEFT JOIN MODULES_V M on M.MOD_ID = R.I_MODULE_SIC_ID
INNER JOIN APP_GEN_CODE_T B on B.ST_CODE = R.REUN_CNRE_ST_CODE
INNER JOIN APP_GEN_CODE_T D on d.ST_CODE = R.CSRE_ST_CODE
where R.EXRC_NUMREXRC = '#form.year_source#'
and B.ST_CLASS_CODE = 'BUD_CNRE'
and d.ST_CLASS_CODE = 'BUD_CSRE'
<cfif #Searchstatut# is not "">
and R.CSRE_ST_CODE = '#Searchstatut#'
</cfif>
<cfif #Searchnumber# is not "">
and R.REUN_NUMREURO = '#Searchnumber#'
</cfif>
ORDER BY R.REUN_NUMRREUN
</cfquery>
<cfcatch type="database">
<!--- PUT THE VARIABLE errorDBquery TO 1 --> Disable the Save button of the form) --->
<cfset SESSION.errorDBquery = 1>
</cfcatch>
</cftry>
<!-------------------------------- GET DATA ON THE MEETING ------------------------------ END --->
<cfset reunionIdList= "0" />
<cfif isdefined("qry_reunion.recordcount")>
<!--- Create the list of meeting number --->
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<!--- create a var with all REUN_NUMRREUN used in this SCRIPT --->
<cfscript>
reunionIdList &= ",";
reunionIdList &= #qry_reunion.REUN_NUMRREUN[i]#;
</cfscript>
</cfloop>
<cfif #qry_reunion.RECORDCOUNT# is 0 AND #searchorg# is not "">
<br><br><cfoutput>#application.ui_lib_Result#</cfoutput>
<cfelse>
<br>
<table class="dataTable">
<thead>
<cfoutput>
<tr>
<th title="#application.ui_lib_numero#">#application.ui_lib_numero#</th>
<th title="#application.ui_lib_organisateur#">#application.ui_lib_organisateur#</th>
<th title="#application.ui_lib_objet#">#application.ui_lib_objet#</th>
<th title="#application.ui_lib_statut#">#application.ui_lib_statut#</th>
<th title="#application.ui_lib_ville#">#application.ui_lib_ville#</th>
<th title=""> </th>
</tr>
</cfoutput>
</thead>
<tbody>
<!-------------------------------- Retrieve info on all unit ------------------------------- START --->
<cfinvoke component="service/meetings" method="getMeetingsUnitLabel" returnvariable="meetingsUnit">
<cfinvokeargument name="meetingsNumber" value="#reunionIdList#">
</cfinvoke>
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<cfoutput>
<form action="reunion_status.cfm?mode=generalite_sta" method="post">
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO[i]#</td>
<td class="cc">
<!-------------------------------- Retrieve info on unit and check that the org_id is still active ------------------------------- START --->
<cfinvoke component="service/units" method="getUnitVersionFromMeetingOrgId" returnvariable="meetingUnitVersion">
<cfinvokeargument name="meetingOrgId" value="#qry_reunion.ORG_ID[i]#">
<cfinvokeargument name="meetingId" value="#qry_reunion.REUN_NUMRREUN[i]#">
<cfinvokeargument name="unitsArray" value="#SerializeJSON(meetingsUnit.VALUES)#">
</cfinvoke>
<cfif StructIsEmpty(meetingUnitVersion) eq false >
<cfif #meetingUnitVersion.VALUES.OBSOLETE# EQ 0>
<cfset unit ="#meetingUnitVersion.VALUES.ORG_CD#"/>
<cfelse>
<cfset unit ="#meetingUnitVersion.VALUES.ORG_CD# (obsolete)" />
</cfif>
#unit#
<cfif #meetingUnitVersion.VALUES.OBSOLETE# EQ 1 AND #meetingUnitVersion.VALUES.IS_ESTAT# eq 1>
<!--- Dsiplay a tooltip when unit is archived --->
<span id="obsoleteMeetingUnit_#i#" style="line-height:30px;">
<img class='my-tooltip' src='pictures/questionmark.gif' style='vertical-align:middle;'>
</span>
<cfset REUN_DATECREA = #DateFormat(qry_reunion.DATECREA[i], "dd/mm/yyyy")# />
<script>
var #toScript(meetingUnitVersion.VALUES.UNIT_VALID_FROM, "unitValidFrom")#;
var #toScript(meetingUnitVersion.VALUES.UNIT_VALID_TO, "unitValidTo")#;
var #toScript(meetingUnitVersion.VALUES.ORG_CD, "unitLabel")#;
var #toScript(REUN_DATECREA, "meetingCreationDate")#;
var #toScript(i, "i")#;
$("##obsoleteMeetingUnit_" + i).tooltipster({
contentAsHTML: true,
interactive: true,
animation: 'grow',
content: $("<span> was " + unitLabel + " <em>(valid from " + unitValidFrom + " to " + unitValidTo +")</em> when the meeting has been created on " + meetingCreationDate +".</span>"),
theme: 'tooltipster-shadow'
});
</script>
</cfif>
<cfelse>
Error
</cfif>
</td>
<td class="cc">#qry_reunion.REUN_OBJET[i]#</td>
<td class="cc">#qry_reunion.NATURE[i]#</td>
<td class="cc">#qry_reunion.VIL_CD[i]#</td>
<td class="cc">
<input type="hidden" name="REUN_NUMRREUN" value="#qry_reunion.REUN_NUMRREUN[i]#">
<input name="#application.ui_lib_chgt_status#" type="submit" value="#application.ui_lib_chgt_status#">
</td>
</tr>
</form>
</cfoutput>
</cfloop>
</tbody>
</table>
</cfif>
</cfif>
Some additional information:
In my DB there is a view of all Units containing current and the history of each unit.
A meeting is linked to one unit but the unit can have several records in the view. And I need to get the correct row of the unit linked to each meeting
I need to display the list of meetings in function of the filters selected in the different drop-down lists.
I create a function getMeetingsUnitLabel for getting data of all units from the list of meetings in parameter. it's allows me to use that for 1 or several meetings.
The second function getUnitVersionFromMeetingOrgId retrieve the correct record on the version of the unit used when the meeting has been created (it used the parameters retrieved from the previous function.
Thank you in advance for your help,
Seb
(Too long for a comment.)
First thing: Read about SQL injection (use <cfqueryparam>) and DOM XSS (use encodeForHtml()). Your page is full of vulnerabilities and it doesn't matter if that's just some intranet/backoffice because security is relevant everywhere.
Second thing: Learn when to use # and when you don't need them.
Finally: Measure the performance of each section. There is getTickCount() to get a rough timing delta for code execution (just don't use it for micro benchmarking). Generally you want to avoid calling heavy functions in a loop (see Big O notation), especially database/IO calls. Retrieve and process data once and then work with the resultset instead of calling subfunctions for each result. You did not tell us what your functions (getMeetingsUnitLabel and getUnitVersionFromMeetingOrgId) actually do, nor how your query performs, so it's hard to recommend anything specific right now.
Also: Consider moving the JavaScript blocks within your loop to a single script block at the end (after the loop). It will be easier to maintain that instead of fiddling around in each table row.
There is a lot of stuff going on here. Let me cover what stands out to me.
Using cfoutput
...
<cfloop from="1" to="#qry_reunion.recordcount#" index="i">
<cfoutput>
...
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO[i]#</td>
...
Is the the ColdFusion way of getting data out of a DB. It looks like how other languages do it. It should really look like this
...
<cfoutput query="qry_reunion">
...
<tr>
<td class="cc">#REUN_NUMREURO#</td>
...
Some places I have worked at really like scoping query variables. In that case it would be
...
<cfoutput query="qry_reunion">
...
<tr>
<td class="cc">#qry_reunion.REUN_NUMREURO#</td>
...
Nested calls
<cfloop
...
<cfinvoke component="service/units" method="getUnitVersionFromMeetingOrgId" returnvariable="meetingUnitVersion">
...
This is just asking to be slow. I would create an SQL user defined function or a view to do whatever this is. I want to put the data collecting work on the DB because the DB knows more about collecting and grouping and joining data than ColdFusion
Tooltip
<span id="obsoleteMeetingUnit_#i#" style="line-height:30px;">
<img class='my-tooltip' src='pictures/questionmark.gif' style='vertical-align:middle;'>
</span>
...
var #toScript(i, "i")#;
$("##obsoleteMeetingUnit_" + i).tooltipster({
contentAsHTML: true,
interactive: true,
animation: 'grow',
content: $("<span> was " + unitLabel + " <em>(valid from " + unitValidFrom + " to " + unitValidTo +")</em> when the meeting has been created on " + meetingCreationDate +".</span>"),
theme: 'tooltipster-shadow'
});
</script>
All this is way to verbose. Not to mention it is probably real slow to become interactive. If you need a fancy tool tip. The pattern should look like this:
<span class="custom_tooltip"
data-unitlabel = "#EncodeForHTMLAttribute(unitLabel)#"
data-unitvalidfrom = "#EncodeForHTMLAttribute(unitValidFrom)#"
data-unitvalidto = "#EncodeForHTMLAttribute(unitValidTo)#"
data-dtCreate = "#EncodeForHTMLAttribute(meetingCreationDate)#"
></span>
Then hook in some document.ready stuff and have it apply the tooltip stuff after everything has loaded.
Conclusion
The amount of HTML generated is about twice as big as it needs to be. All of this should be much smaller and quicker.
Edit - There are some customer accounts that are reporting a $0 balance due on their online accounts but there is an actual balance due. It is with these accounts only that the PDFs will not open. Data import issue at this point?
I have a set of CF functions in which new PDFs are generated from database records and available on user accounts for download or viewing. The code has worked great up until a couple weeks ago, but now the new or old (previous monthly bills) PDFs will not open (corrupt) on the user account pages. The record data has not been changed or modified. Could this be CF update issue or what could have caused files to now generate corrupt? Any help is appreciated.
PDF Analysis of the corrupt PDF files gives:
PDF Errors:
Open file.
0x80410108 - E - The end-of-file marker was not found.
- File: 11118749.pdf
0x8041010A - E - The 'startxref' keyword or the xref position was not found.
- File: 11118749.pdf
0x80410108 - E - The end-of-file marker was not found.
- File: 11118749.pdf
Close file.
CF PDF Generation Code:
<cfcomponent>
<!---***************************************************************************--->
<cffunction name="getBill" access="public" returntype="query">
<cfargument name="billID" required="yes" default="">
<cfquery name="getPayment" datasource="#application.dsnName#" username="****" password="****">
SELECT * FROM ccos_cust_bill
WHERE billID = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.billID#">
</cfquery>
<cfreturn getPayment>
</cffunction>
<!---***************************************************************************--->
<!---***************************************************************************--->
<cffunction name="getCustBills" access="public" returntype="query">
<cfargument name="accountNum" required="yes" default="">
<cfquery name="getCustBills" datasource="#application.dsnName#" username="****" password="****">
SELECT * FROM ccos_cust_bill
WHERE accountNum = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.accountNum#">
ORDER BY billDate DESC, billID DESC
</cfquery>
<cfreturn getCustBills>
</cffunction>
<!---***************************************************************************--->
<!---***************************************************************************--->
<cffunction name="addBill" access="public" returntype="string">
<cfargument name="formvalues" required="yes" default="">
<cfquery name="addBill" datasource="#application.dsnName#" username="****" password="****">
INSERT INTO ccos_cust_bill (billID, accountNum, billDate, dueDate, billTotal)
VALUES (
<cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.formvalues.billID#">,
<cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.formvalues.accountNum#">,
<cfqueryparam cfsqltype="cf_sql_date" maxlength="20" value="#DateFormat(arguments.formvalues.billDate, "yyyy-mm-dd")#">,
<cfqueryparam cfsqltype="cf_sql_date" maxlength="20" value="#DateFormat(arguments.formvalues.dueDate, "yyyy-mm-dd")#">,
<cfqueryparam cfsqltype="cf_sql_decimal" scale="2" maxlength="20" value="#arguments.formvalues.billTotal#">
)
</cfquery>
<cfset addOK = "Y">
<cfreturn addOK>
</cffunction>
<!---***************************************************************************--->
<!---***************************************************************************--->
<cffunction name="getBillPDF" access="public" returntype="query">
<cfargument name="billID" required="yes" default="">
<cfargument name="accountNum" required="yes" default="">
<cfquery name="getPayment" datasource="#application.billsDsnName#" username="****" password="****">
SELECT * FROM ccos_bills
WHERE billID = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.billID#">
AND accountNum = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.accountNum#">
</cfquery>
<cfreturn getPayment>
</cffunction>
<!---***************************************************************************--->
<!---***************************************************************************--->
<cffunction name="getNextDueDate" access="public" returntype="string">
<cfargument name="accountNum" required="yes" default="">
<cfquery name="getNextDueDate" datasource="#application.dsnName#" username="****" password="****" maxrows="1">
SELECT dueDate FROM ccos_cust_bill
WHERE accountNum = <cfqueryparam cfsqltype="cf_sql_integer" maxlength="20" value="#arguments.accountNum#">
AND dueDate >= <cfqueryparam cfsqltype="cf_sql_date" maxlength="20" value="#DateFormat(now(), "yyyy-mm-dd")#">
ORDER BY dueDate
</cfquery>
<cfreturn getNextDueDate.dueDate>
</cffunction>
<!---***************************************************************************--->
</cfcomponent>
CF View PDF Code:
<cfparam name="URL.billID" default="">
<cfset getBillPDF = application.billCFC.getBillPDF('#URL.billID#','#session.accountNum#')>
<cfif getBillPDF.RecordCount GT 0>
<cfoutput query="getBillPDF">
<cfset fileData = "#BinaryDecode(billData, "Base64")#">
<cfheader name="content-disposition" value="inline; filename=#billID#.pdf" />
<cfcontent type="application/pdf" variable="#fileData#" />
</cfoutput>
<cfelse>
You are not authorized to view this bill.
</cfif>
PDF Import into Database
<!--- CCOS Bill PDF Data --->
<cfquery name="deleteData" datasource="#application.billsDsnName#" username="#application.billsDsnUser#" password="#application.billsDsnPass#">
DELETE FROM ccos_bills WHERE billDate < '#DateFormat(DateAdd("d", -180, now()), "yyyy-mm-dd")#'
</cfquery>
<!--- Check to see how many files Exist --->
<cfdirectory action="list" directory="#ExpandPath('.')#\files" name="filelist">
<cfset fileCount = 0>
<cfoutput query="filelist">
<cfif name CONTAINS "ccos_cust_bill_pdf"><cfset fileCount = fileCount + 1></cfif>
</cfoutput>
<!--- Loop over the files and Load the new data --->
<cfloop from="1" to="#fileCount#" index="i">
<cfquery name="insertData" datasource="#application.billsDsnName#" username="#application.billsDsnUser#" password="#application.billsDsnPass#">
LOAD DATA LOCAL INFILE '#Replace(ExpandPath('.'), "\", "\\", "ALL")#\\files\\ccos_cust_bill_pdf#i#.txt' IGNORE
INTO TABLE `ccos_bills`
FIELDS OPTIONALLY ENCLOSED BY '"'
TERMINATED BY '|'
<!---IGNORE 1 LINES--->
(`accountNum`, `billID`, `billDate`, `billData`);
</cfquery>
</cfloop>
<cfquery name="fixbillDate" datasource="#application.billsDsnName#" username="#application.billsDsnUser#" password="#application.billsDsnPass#">
UPDATE ccos_bills SET dateCreated = '#DateFormat(now(), "yyyy-mm-dd")#' WHERE dateCreated IS NULL
</cfquery>
<!---***********************************************************************************--->
I am currently using Binding to grab values from a database. Depending on what the user selects from a pull down it shows the results from the database. Currently I am able to show one result but I need to show multiple results if the query brings back more then 1 value. Here is my current code.
<cffunction name="getServiceType" access="remote" returnType="array">
<cfargument name="CATG_NAME" type="string" required="true">
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<cfquery name="getServiceType" datasource="#dsource#">
select distinct SRTY_NAME
from Somedatabase
where (CATG_SPRS_NAME = <cfqueryparam value="#ARGUMENTS.CATG_NAME#" cfsqltype="cf_sql_varchar"> OR CATG_DEPT_SPRS_NAME = <cfqueryparam value="#ARGUMENTS.CATG_NAME#" cfsqltype="cf_sql_varchar">) AND EVLN_REQD_FLAG IS NOT NULL
order by SRTY_NAME
</cfquery>
<cfloop index="i" from="1" to="#getServiceType.recordcount#">
<cfset result[i][1]=getServiceType2.SRTY_NAME[i]>
<cfset result[i][2]=getServiceType2.SRTY_NAME[i]>
</cfloop>
<cfreturn result>
</cffunction>
This generates the 1st pull down list
<cffunction name="getUnion" access="remote" returnType="array">
<cfargument name="SRTY_NAME" type="string" required="true">
<cfset var result=ArrayNew(1)>
<cfquery name="union_rq" datasource="#dsource#">
select U.UNI_NAME, S.SRTY_NAME
from Somedatabase U JOIN Someotherdatabase S ON U.SRTY_NBR = S.SRTY_NBR
where S.SRTY_NAME = <cfqueryparam value="#ARGUMENTS.SRTY_NAME#" cfsqltype="cf_sql_varchar">
</cfquery>
<cfset result[1]=union_rq.UNI_NAME>
<cfreturn result>
</cffunction>
The first list would have an option list Hotel Training and the second query should show both Maids and Cooks. Right now it only shows Maids. I tried to create a list or another array but have not be able to get it to display the results. Below is my Coldfusion call for the display. It is fine to display with commas between the results like Maids,Cooks
<tr id="union">
<td></td>
<td>Union Attached:
<cfinput name="uni_name"
bind="cfc:servicetype.getUnion({service_type})"
bindonload="false"
/></td></tr>
Any advice would be greatly appreicated.
In my CF component, I tried to filter data from user input (getSearchString) and run the code, I having problem with WHERE function. Can suggestion what is the correct way?
<cffunction name="getParks" access="remote" returntype="struct">
<cfargument name="page" required="true" />
<cfargument name="pageSize" required="true" />
<cfargument name="gridsortcolumn" required="true" />
<cfargument name="gridsortdirection" required="true" />
<cfargument name="getSearchString" default="" />
<cfif arguments.gridsortcolumn eq "">
<cfset arguments.gridsortcolumn = "parkName" />
<cfset arguments.gridsortdirection = "asc" />
</cfif>
<cfquery name="parks" datasource="cfdocexamples">
select parkName, parkType, city, state
from parks
where <cfqueryPARAM value = "#getSearchString#" CFSQLType = "CF_SQL_VARCHAR">
order by #arguments.gridsortcolumn# #arguments.gridsortdirection#
</cfquery>
<cfreturn queryconvertforgrid(parks, page, pagesize) />
It seems to be a simple sql bug. The field which you would like to compare with your searchstring is missing.
Should rather be:
<cfquery name="parks" datasource="cfdocexamples">
select parkName, parkType, city, state
from parks
where parkName = <cfqueryPARAM value = "#getSearchString#" CFSQLType = "CF_SQL_VARCHAR">
order by #arguments.gridsortcolumn# #arguments.gridsortdirection#
</cfquery>
acctually not around param but around getSearchString:
WHERE parkName LIKE ... "%#getSearchString#%" ... But beware of performance issue with LIKE, also if you have large number of entries, dataGrid doesn't do real paging. Full blown solution depends on your database type.