Hey fellow CF fans, it is Monday, and that means another blog entry. This time I’m throwing together a little code snippet that uses a little-known feature of CFQuery that was included in CF2021 but rarely talked about.
As you might know, when Adobe ColdFusion returns a query, it returns it in a special style of struct, which you can iterate over and just generally use to display data, do calculations, the whole bit. But sometimes, you just want to dump the return to screen, especially when it is tabular data. In the past, you would probably do something like this:
<table> <cfoutput query="nameofquery"> <tr> <td>#somevariable#</td> <td>#anothervariable#</td> </tr> </cfoutput> </table>
And guess what, that works! But what if you want more from your table? Like, for example, search? Pagination? STYLE! Well, in that case, you might choose to leverage the free DataTables plugin. What is neat about DT is that you can build a table, then apply DT to it and it will paginate it, the whole 9 yards. But DT has way more features than that. You can, as it happens, point it at some JSON and it will merrily iterate over it and build your table for you.
That’s where the new “returnType=’json/array'” feature of CFQuery comes in. Instead of returning as your standard, run of the mill query struct, ColdFusion will instead pull the resultset out of the structure (if you want the WHOLE THING in JSON, you would set ‘json/struct’) and return you back a lovely JSON object.
Their powers combined, you’ve got a nice quick way to huck a bunch of data into your page with all the bells and whistles that DataTables provides. Let’s grab some code and see what we got.
First, we’re going to build the endpoint. For simplicity’s sake, I’m just making this a .cfm page sitting in the same folder. You can make this a cfc, expose it as an endpoint, the works, but here we’re going easy. The name I’ve chosen is getData.cfm.
<cfscript> resultArray = []; structthing = {"item" = "item1", "notes" ="notes1", "done"="yes"} arrayAppend(resultArray, structthing); structthing = {"item" = "item2", "notes" ="notes2", "done"="no"} arrayAppend(resultArray, structthing); structthing = {"item" = "item3", "notes" ="notes3", "done"="no"} arrayAppend(resultArray, structthing); structthing = {"item" = "item4", "notes" ="notes4", "done"="yes"} arrayAppend(resultArray, structthing); function arrayToQuery(data) { return data.reduce(function(accumulator, element) { element.each(function(key) { if (!accumulator.keyExists(key)) { accumulator.addColumn(key, []); } }); accumulator.addRow(element); return accumulator; }, QueryNew("")); } resultQuery = arrayToQuery(resultArray); </cfscript> <cfquery name="converttojson" returntype="json/array" dbtype="query"> SELECT * from resultQuery </cfquery> <cfscript> writeOutput(converttojson); </cfscript>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Datatable Demo</title> <link href="https://cdn.datatables.net/1.11.1/css/jquery.dataTables.min.css" rel="stylesheet" /> </head> <body> <table id="apitable" name="apitable" class="dataTable" style="width: 100%"> <thead> <tr> <th>Item</th> <th>Notes</th> <th>Done?</th> </tr> </thead> <tbody></tbody> </table> <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script> <script src="https://cdn.datatables.net/1.11.1/js/jquery.dataTables.min.js"></script> <script> $(document).ready(function() { $('#apitable').DataTable( { ajax: { url: 'getData.cfm', dataSrc: '' }, columns: [ {data: 'item'}, {data: 'notes'}, {data: 'done'} ] } ); } ); </script> </body> </html>
See Mark, I knew I should have asked you to take a crack at my last app. Where were you a couple months back with this. Now you can fix the rest of my app while I convert my existing code to using this trick. This will be really cool, the next step is you integrate HighCharts to pull from this Data Table you got going on and boom, you got that one query json return making a table and a chart. As a happy byproduct you’ll have done all the work I did on my app the hard way and I can steal it. Nice post.
You must be logged in to post a comment.