Gregory's Blog
long meetins stink

Dynamically Populating Kendo MultiSelects


As we previously mentioned, the Kendo MultiSelect widget offers significant enhancements to a traditional dropdown menu and can be used to replace a long list of checkboxes. In this article, we will take a deep dive into the Kendo MultiSelect, show how it can be prepopulated with existing values, and how to dynamically populate it using cascading dropdowns.

Like the rest of the posts in this series, we will be using ColdFusion on the server side, however, it should be easily understood if you use a different server-side language, and you should be able to follow along.



Visual Demonstration of Kendo's MultiSelect vs HTML MultiSelect

A picture is worth a thousand words. I am going to contrast the Kendo MultiSelect against traditional HTML checkboxes to visually convey the benefits of using the Kendo MultiSelect.

In the following interfaces, we are prepopulating the form with the US states on the Pacific seaboard selected.


Kendo MultiSelect

As you can see here, with the Kendo MultiSelect the selected values are front and center allowing the user to quickly see what is selected without forcing them to scroll down a long list of items. The Kendo MultiSelect also has search functionality to allow the user to quickly select additional values. The Kendo MultiSelect is also much more elegant and it takes up less space on the screen.

The Kendo MultiSelect's ability to put information front and center makes it a perfect tool to conceptualize related groups of information, however, in order to convey this we need to be able to dynamically populate this list.


Traditional HTML Multi-Select

The traditional multi-select requires you to scroll way down to see Oregon and Washington that are selected, and you better make sure not to accidentally click on one of the items while scrolling or the selection will be gone!


Dynamically Removing the Selected Kendo MultiSelect Options

To remove all of the selected values in the Kendo MultiSelect, simply pass an empty array to the MultiSelect value method like so:

$("#stateDropdown").kendoMultiSelect({
	placeholder: "Select...",
	autoBind: false,
	dataTextField: "name",
	dataValueField: "id",
	filter: "contains",
	dataSource: stateDs,
	value: []
}).data("kendoMultiSelect");

Populating a Kendo MultiSelect With Initial Values

Use the MultiSelect value method to populate the values of a Kendo MultiSelect.

You can either use an array with comma-separated values or an array of structures for the value.  This value must have the same value and datatype as the data element that is used to populate the dataValueField. If the value and the data type do not match a data element used to populate the dataValueField, the value will be ignored. We will illustrate this below.

All of these examples are valid:

// Displays United States
value: [{ name: "United States", id: 233 }] // Note: the name will be ignored. 
value: [{ id: 233}]
value: [233]
// Displays United States, United States Minor Outlining Areas
value: [233,234]
value: [{id:233},{id:234}]

However, these examples do not work. See comments in code:

[{ name: "United States" }] // United States does not match a data element in the dataValueField and will be ignored
"233,234,235"// Missing array (the square brackets)

Dynamically Populating a Kendo MultiSelect


Overview

To dynamically populate a Kendo MultiSelect, we need to inspect data using either AJAX or using the Kendo DataSource and prepare the data for the MultiSelect value method.

If you're using jQuery AJAX, and the data from the server is already a comma-separated string or an array of structures, you may be able to dump the data into the Kendo MultiSelects value method. Otherwise, you will have to prepare the string or array by looping through the data.

If you're inspecting data from a Kendo Datasource, we will use a similar approach that we would use to interrogate the data using jQuery Ajax- we will loop through the data triggered by a parent Kendo widget and populate the values array using the JavaScript push method and use the new array in the Kendo MultiSelect value method. 

In this article, we will focus on interrogating data from the Kendo DataSource.


Potential Use Cases

Unlike the traditional HTML MultiSelect, a Kendo MultiSelect can be prepopulated with values to allow the user to easily visualize and interact with related groups of data. I often populate the MultiSelect widget to allow the users to conceptualize related data with a predefined starting point.  

There are many other reasons to dynamically populate the MultiSelect. For example, we can clean up the selected values in a MultiSelect if the child values don't relate to other parent data. For example, in our previous Cascading MultiSelect article, we dynamically removed states from a child MultiSelect when the state's country was removed in the parent country MultiSelect menu. 


MultiSelect Dynamic Population Demonstration

The following example allows the user to select a world region that they are interested in exploring. Once the user selects a world region, the region states will be dynamically populated in the child state multi-select.

We will go over the details of this code later in this article.

Countries by subregion

Extracting Data from a Kendo DataSource

To extract the data from a Kendo DataSource, we need to use Kendo's data method on the Kendo DataSource. Unfortunately, we can't use this data to directly populate the MultiSelect's value method as the JSON extracted from the Kendo DataSource has been transformed into a specialized Kendo Observable Array JavaScript object. Instead, we need to loop through the data and create a string of values separated by commas using the JavaScript push method.

The populateCountry function below performs all of the necessary steps to extract the data from the countryDs data source and populates the country MultiSelect with values. This function is invoked using the change method on the parent subregion dropdown when the user selects a country. The full code is provided at the end of this article.

This function will use the data method on the countryDs Kendo DataSource that was consumed via the change function invoked when the user selects a subregion. Here, we don't need to use the Kendo fetch or read method as the data source already consumed the service endpoint when a region was selected. We will cover the fetch and read methods in future articles, but they don't apply here.

After using the Kendo DataSource's data method, we will create an empty countryIdList array to hold the list of values that we will later use in the MultiSelect's value method and loop through the data, which is a specialized JavaScript array.

Our loop will be a simple JavaScript for loop, and we will continue to loop through the records until there are no more records in the Kendo Observable array.

Inside this loop, we will extract the items that we need to populate the Kendo MultiSelect. In this example, we are getting the id, which is the primary key of the country table. Once the id has been extracted, we will use the JavaScript push method to push the value into the new countryIdList array that we just created.

After the loop has been completed and all of the ids have been saved to our new array, we will use this countryIdList to populate the MultiSelect using the widgets value method.

Here is the function:


The populateCountry function

// Populate the selected MultiSelect values from the datasource	
function populateCountries(e){
	// Get the data from the datasource
	var data = countryDs.data();
	// Create an array that we will use to populate the dropdown
	var countryIdList = [];
	// Loop through the data to create an array to send to the multi-select
	for (var i = 0; i < data.length; i++) {
		// Get the countryId
		var countryId = data[i].id;
		// Populate our new array with the value surrounded by qoutes
		countryIdList.push(countryId);
	}//..for (var i = 0; i < capabilityDsData.length; i++) {
	// At the end of the loop, opulate the multiSelect with the array that we just built
	countryDropdown.value(countryIdList);
}//..function...

This entry was posted on October 21, 2022 at 12:45 AM and has received 568 views.

Working with JSON and JavaScript


In my series of ColdFusion and Kendo UI articles, I have covered how to use JSON to populate the Kendo UI widgets. However, JSON can be used for much more than that!

JSON objects can be used by nearly every modern language, whether it is C#, Java, or ColdFusion. I personally use JSON nearly every time that I want to transfer data from the server to the client side using JavaScript.

In this article, we will take a quick break from Kendo UI and will introduce you to JSON and AJAX, show you how to create and consume JSON, how to consume JSON on the server using AJAX, and how to work with these JSON objects with JavaScript. Like our other articles, I will also provide the code and real-time examples. 



What is JSON?

Simply put, JSON is a popular string format that is used to exchange data between applications. In web applications, it is typically used to transfer data with AJAX or used when interacting with an API. 

JSON typically contains an array of structures, however, it also can be a single double-quoted string. JSON is not inherently an object but describes object data in JavaScript and other languages. However, once JSON is successfully parsed by JavaScript (or other languages), the JSON information is transformed into a native JavaScript object.


JSON Structure

The example shown below is a typical JSON structure that puts the data elements within an array of structures. However, as we mentioned before, you can also use simple strings in JSON as long as the string is enclosed by double quotes.

The following elements can be used in the JSON string:

  • strings enclosed in double quotes
  • numbers are not quoted
  • objects, typically a structure of key pairs enclosed by braces
  • arrays surrounded by square brackets.
  • boolean values do not use quotes
  • null uses null without quotes

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON for more detailed information.

Here is an example of all of these types. This example is used in Galaxie Blog to populate role dropdowns, and we will be using something quite similar in an upcoming article.

[
   {
      "Description":"All functionality.",
      "RoleId":1,
      "RoleName":"Administrator",
      "Capabilities": ["AssetEditor",
		"EditCategory",
		"EditComment",
		"EditFile",
		"EditPage",
		"EditPost",
		"EditProfile",
		"EditServerSetting",
		"EditSubscriber",
		"EditTemplate",
		"EditTheme",
		"EditUser",
		"ReleasePost"],
      "Notes":null,
      "Active":true
   }
]

JSON Data Handles and Other Extraneous Information

While not technically part of the JSON specification, some HTML5 widget libraries, such as jsGrid, require the JSON to have a data handle. The data handle in the example below is the "data": string.

Some widgets, including Kendo UI, also require the JSON to have a total structure in the JSON to display the total number of records in a grid for pagination purposes.

JSON is a flexible specification, as long as you follow the basic rules, this information can be incorporated. Extra information in the JSON can also be ignored.

JSON Example with a Data Handle

{
   "data":[
      {
         "Email":"myemail@gmail.com",
         "Description":"We have covered how to use JSON to populate Kendo UI objects, but JSON can do much more than that! JSON can be used in nearly every language, however, in this article, we will discuss how to work with JSON objects in JavaScript.",
         "BlogSortDate":"September, 16 2022 23:32:00",
         "MimeType":null,
         "PostAlias":"Working-with-JSON-and-JavaScript",
         "Released":false,
         "Body":"In my series of ColdFusion and Kendo UI articles, I have covered how to use JSON to populate the Kendo UI widgets. However, JSON can be used for much more than that!",
         "Title":"Working with JSON and JavaScript",
         "NumViews":0,
         "Date":"September, 20 2022 00:00:00",
         "FullName":"Gregory Alexander",
      }
   ]
}

JavaScript JSON Related Functions 

The following static JavaScript functions are used with JSON:


Extracting Data from a JSON String 

To extract the value of a single element in the JSON string, use variableName.key. This is identical to getting a value stored in ColdFusion structures. For example, to get the post title in the JSON above, use data.Title.

You can also use bracket notation, just as you would get the value of a ColdFusion HQL column, using variableName["key"]. Using this notation we would use data["Title"]. Both of these statements will do the same thing.


A Brief Introduction to AJAX and JSON 

There are many other ways to elicit a JSON response from the server, but this article will focus on using AJAX on the client side to send an asynchronous HTTP (Ajax) request to a ColdFusion Component or function. The ColdFusion template on the server will process the data and send a JSON response back to the calling AJAX function. We will then inspect the AJAX response and deliver information back to the user using JavaScript.

This AJAX request may be made either by a traditional AJAX statement or performed automatically using the Kendo DataSource when we declare a Kendo DataSource or initialize a Kendo UI widget. 


AJAX Automatically Transforms JSON into JavaScript

It is important to note that if you are using AJAX to consume JSON on the server, the JSON string will automatically be converted into a native JavaScript object when using "json" as the dataType argument. After the JSON string is transformed, you will need to use native JavaScript methods to get at the underlying data in the JavaScript object.


What is the Difference Between AJAX and getJSON?

You may either use jQueries AJAX or getJSON method to fetch JSON data using a get HTTP request. The getJSON function is a simplified version of jQuery's AJAX- however, underneath the hood, the two methods are the same. 

I prefer using the AJAX method as it provides more customization, in particular, I can either enable or disable caching. Technically, there are ways to disable caching using the getJSON function, but they either affect all of the AJAX statements with a global AJAX cache var or they resort to using a timestamp method which I find to be a bit kludgy.

The arguments for the getJSON function are: 

$.getJSON(url, data, success);

Parsing JSON that has been Transformed into a JavaScript Object

There are multiple ways to get the JSON keys and values in a JavaScript object. However,  the approach will differ depending on if you want to extract a single value or multiple records. 

Extracting a Single Value

If you're using a single row of data, or know the index of the row that you want to extract, you can use data[index].key

For example, to get the state name in our result, use data[0].name. JavaScript arrays start at zero, so the first row uses an index of 0. This is identical to the approach used to parse a JSON string, although using JavaScript requires that you specify an index to get the proper row.

Like JSON, you can also use the bracket notation like so:

alert(data[0]['name'])

Here is a full example with the AJAX call:

jQuery.ajax({
	type: 'post', 
	url: '<cfoutput>#application.baseUrl#</cfoutput>/demo/WorldCountries.cfc',
	data: { // method and the arguments
		method: "getStates",
		state: "Washington"
	},//..data: {
	dataType: "json",
	success: result, // calls the result function.
	// Simplified error handling
	error: function(ErrorMsg) {
	   console.log('Error' + ErrorMsg);
	}
});//..jQuery.ajax({

function result(data){
	alert(data[0].name);
}


Looping Through Multiple Records

If you have multiple records, you can loop through the JSON and retrieve an item using the following script. I am using bracket notation in this script.

for(var i=0; i < data.length; i++){
	// Get the data held in the row in the array using bracket notation
	alert(data[i]['name'])
}

A complete example with an HTML form populated by AJAX and JSON. A real-time example is provided below.

<script>
	// Get state data from the server
	jQuery.ajax({
		type: 'post', 
		url: '<cfoutput>#application.baseUrl#</cfoutput>/demo/WorldCountries.cfc',
		data: { // method and the arguments
			method: "getStates",
			countryId: 233 //United States
		},//..data: {
		dataType: "json",
		success: result, // calls the result function.
		// Simplified error handling
		error: function(ErrorMsg) {
		   console.log('Error' + ErrorMsg);
		}
	});//..jQuery.ajax({

	function result(data){
		for(var i=0; i < data.length; i++){
			// Get the name of the state held in the row in the array and push it to the form
			$("#state" + i).val(data[i]['name']);
		}//for(var i=0; i < result.data.length; i++){..
	}//function result(data){..
</script>

<p>This form is populated by AJAX and JSON</p>
<table width="100%" class="k-content">
<!--- Loop 66 times, some states are territories here --->
<cfloop from="0" to="65" index="i">
  <tr>
	<td align="left" valign="top" class="border" colspan="2"></td>
  </tr>
  <tr>
	<td align="right" style="width: 20%">
		<label for="state<cfoutput>##</cfoutput>">State:</label>
	</td>
	<td>
		<!-- Create the state text input -->
		<input type="text" id="state<cfoutput>#i#</cfoutput>" name="state<cfoutput>#i#</cfoutput>" value="" style="width: 95%">
	</td>
   </tr>
</cfloop>
   <tr>
	 <td align="left" valign="top" class="border" colspan="2"></td>
   </tr>
</table>


Inspecting the Entire Object

Finally, you may inspect the entire object using JavaScript like so:

function result(data){
	// Loop thru the outer object (data)
	for(var i=0; i < data.length; i++){
		// Get the data held in the row in the array. 
		var obj = data[i];
		// Create an inner for loop
		for(var key in obj){
			// Set the values. 
			var attrName = key;
			var attrValue = obj[key];

			alert(attrName);
			alert(attrValue);
		}
	}
}

Complete Example with AJAX:

<script>
	// Get state data from the server
	jQuery.ajax({
		type: 'post', 
		url: '<cfoutput>#application.baseUrl#</cfoutput>/demo/WorldCountries.cfc',
		data: { // method and the arguments
			method: "getStates",
			state: "Washington"
		},//..data: {
		dataType: "json",
		success: result, // calls the result function.
		// Simplified error handling
		error: function(ErrorMsg) {
		   console.log('Error' + ErrorMsg);
		}
	});//..jQuery.ajax({

	function result(data){
		// Loop thru the outer object (data)
		for(var i=0; i < data.length; i++){
			// Get the data held in the row in the array. 
			var obj = data[i];
			// Create an inner for loop
			for(var key in obj){
				// Set the values. 
				var attrName = key;
				var attrValue = obj[key];
				// Pop the values up
				alert('Attribute Name: ' + attrName);
				alert('Attribute Value: ' + attrValue);
			}//for(var key in obj){..
		}//for(var i=0; i < data.length; i++){..
	}//function result(data){..
</script>

This page retrieves the state using AJAX and will pop up an alert showing the keys and values found in the object. There should be 8 popups here.


We will use some of what we learned here today in our next article.


Further Reading

This entry was posted on September 22, 2022 at 11:22 PM and has received 280 views.

Using ColdFusion to Populate Kendo UI Widgets


There are multiple ways to populate Kendo widgets with data. Take a simple dropdown, you can populate a dropdown the same way that you would build a simple HTML dropdown using a ColdFusion query loop or create a static dropdown by building the HTML option tags in the dropdown manually. You can also use Javascript arrays as the data source for a dropdown, or other Kendo HTML5 widgets, but to leverage the full dynamic potential of the Kendo widgets, you need to use a server-side language, such as ColdFusion, to query a database and return the data as JSON. 


Table of Contents


Populating a Kendo widget with static HTML

Here is an example of a simple Kendo dropdown list using static HTML:

<script>
	// ---------------------------- Kendo datasource for the dropdown. ----------------------------
	var bestLanguageDs = new kendo.data.DataSource({
		transport: {
			read: {
				cache: false,
				// Note: since this template is in a different directory, we can't specify the cfc template without the full path name.
				url: function() { // The cfc component which processes the query and returns a json string. 
					return "<cfoutput>#application.baseUrl#</cfoutput>/demo/Demo.cfc?method=getBestLanguage"; 
				}, 
				dataType: "json",
				contentType: "application/json; charset=utf-8", // Note: when posting json via the request body to a coldfusion page, we must use this content type or we will get a 'IllegalArgumentException' on the ColdFusion processing page.
				type: "GET" //Note: for large payloads coming from the server, use the get method. The post method may fail as it is less efficient.
			}
		} //...transport:
	});//...var bestLanguageDs...

	// ---------------------------- Kendo dropdown. ----------------------------
	var serverSideLanguageDropdown = $("#serverSideLanguageDropdown").kendoDropDownList({
		optionLabel: "Select...",
		autoBind: false,
		dataTextField: "label",
		dataValueField: "value",
		filter: "contains",
		dataSource: bestLanguageDs,
	}).data("kendoDropDownList");
</script>


 

Populating the Kendo DataSource with a local Javascript array

For most widgets, you can also bind the Kendo dataSource of the widget to a local Javascript array. This is useful if you don't have the data in the database. Note the arrServerSideLanguage Javascript array is bound to the DataSource variable in the Kendo dropdown. We will cover the Kendo DataSource more extensively in the section below.

<script>
	// Create a Javascript array to populate the Kendo dropdown
	var arrServerSideLanguage = [
		{"label":"Adobe ColdFusion","value":"ACF"},
		{"label":"Lucee","value":"Lucee"}
	]	

	// Create the Kendo dropdown
	var serverSideLanguage = $("#serverSideLanguage").kendoDropDownList({
		optionLabel: "Select...",// Default label
		dataTextField: "label",// Dropdown label
		dataValueField: "value",// Dropdown value
		filter: "contains",// Search filter on the dropdown
		dataSource: arrServerSideLanguage,// The datasource takes the Javascript array to populate the control
	}).data("kendoDropDownList");
</script>


Binding the Kendo control to a ColdFusion remote data service

Most often you will be binding a Kendo widget to a remote endpoint. This will be a multi-step process. 

Don't worry if you don't completely understand this tutorial, this article is meant as an introduction to the process and we will cover these steps again.

  1. First, we need to create a Kendo DataSource that will handle our Ajax operations and call a ColdFusion server-side template. In this example, our service endpoint is Demo.cfc.
  2. Our endpoint will be a component on a ColdFusion server that retrieves data from a database and packages the data into a JSON object. In order to do this, we need to download the CfJson component for ColdFusion.
  3. Once the data is prepared on the server, we will return it to the client using Ajax and pass the JSON data object to the Kendo widgets DataSource.

Create a Kendo DataSource and the dropdown on the client to invoke the ColdFusion service

The Kendo DataSource is a component that allows you to use local Javascript arrays or remote XML, JSON, or JSONP data to populate the various Kendo controls. The DataSource allows for server-side sorting, paging filtering, grouping, and data aggregates. 

The Kendo DataSource handles the necessary AJAX operations and makes an AJAX post to the server found in the URL argument below.

You will see other Kendo examples where all of the Kendo DataSource logic is embedded inside of the widget. I typically separate the Kendo DataSource from the widget as it allows me to potentially reuse the data for other controls. 

<script>
	// ---------------------------- Kendo datasource for the dropdown. ----------------------------
	var bestLanguageDs = new kendo.data.DataSource({
		transport: {
			read: {
				cache: false,
				// Note: since this template is in a different directory, we can't specify the cfc template without the full path name.
				url: function() { // The cfc component which processes the query and returns a json string. 
					return "<cfoutput>#application.baseUrl#</cfoutput>/demo/Demo.cfc?method=getBestLanguage"; 
				}, 
				dataType: "json",
				contentType: "application/json; charset=utf-8", // Note: when posting json via the request body to a coldfusion page, we must use this content type or we will get a 'IllegalArgumentException' on the ColdFusion processing page.
				type: "GET" //Note: for large payloads coming from the server, use the get method. The post method may fail as it is less efficient.
			}
		} //...transport:
	});//...var bestLanguageDs...

	// ---------------------------- Kendo dropdown. ----------------------------
	var serverSideLanguageDropdown = $("#serverSideLanguageDropdown").kendoDropDownList({
		optionLabel: "Select...",
		autoBind: false,
		dataTextField: "label",
		dataValueField: "value",
		filter: "contains",
		dataSource: bestLanguageDs,
	}).data("kendoDropDownList");
</script>

Download the CfJson component for ColdFusion (if you don't already have it)

In order to query a database and return the data as a JSON object to the client, we need to use ColdFusion on the server-side with a custom CFJson component. If you want to follow along, you can download this component from GitHub at https://github.com/GregoryAlexander77/CfJson.

Of course, we also need to use jQuery for the Ajax operations, but Kendo UI for jQuery requires jQuery so this should not be an issue.

Create a server-side function to use as the ColdFusion endpoint.

This function will query the database and return the data as a JSON object back to the client. The following function will be placed in the Demo.cfc component that I use for demonstration purposes. The function access argument must be remote when performing Ajax operations. Note the returnFormat="json" argument. This must be set to json, otherwise, the function will return plain text or WDDX and the client-side Ajax will fail.

Note: I don't exactly have a 'ServerLanguage' table anywhere in a database, so in this example, I will mimic a query object by building it in code.

<cffunction name="getBestLanguage" access="remote" returnformat="json" output="true"
	hint="Returns a JSON object back to the client to populate a Kendo dropdown. This function does not take any arguments">

	<!--- Create a ColdFusion query using CFScript. --->
	<cfscript>
		serverLanguage = queryNew("label,value","varchar,varchar", 
			[ 
				 {label="Adobe ColdFusion",value="ACF"}, 
				 {label="Lucee", value="Lucee"}
			]); 
	</cfscript>

	<!--- Now convert the query object into JSON using the convertCfQuery2JsonStruct in the CFJson.cfc and pass in the 'serverLanguage' query --->
	<cfinvoke component="#application.cfJsonComponentPath#" method="convertCfQuery2JsonStruct" returnvariable="jsonString" >
		<cfinvokeargument name="queryObj" value="#serverLanguage#">
		<cfinvokeargument name="contentType" value="json">
		<cfinvokeargument name="includeTotal" value="false">
		<!--- Don't include the data handle for Kendo dropdowns --->
		<cfinvokeargument name="includeDataHandle" value="false">
		<cfinvokeargument name="dataHandleName" value="">
		<!--- Set to true to force the column names into lower case. --->
		<cfinvokeargument name="convertColumnNamesToLowerCase" value="false">
	</cfinvoke>

	<cfreturn jsonString>

</cffunction>


Further Reading

This entry was posted on July 13, 2022 at 10:04 PM and has received 385 views.

Convert a ColdFusion Query into a JSON Object


I have used various HTML5 widgets extensively for the last decade and will share the functions that I use to convert ColdFusion objects returned from a database into JSON. In this article, I will highlight some of the logic in the code and show you how to use this for a variety of use cases.



What Does This Component Do?

These functions are a critical component of all of my HTML5 applications. These functions will convert both a ColdFusion query as well as a ColdFusion ORM array object into JSON that is passed back to the calling Ajax function. Unlike ColdFusion's native JSON functions, this will return the column names in the proper case rather than returning the column names in uppercase.

The function was originally created by Adrian Moreno. I modified this function nearly a decade ago and has been in use in several production environments over the last 10 years.  It is also used extensively in my open-source Galaxie Blog which is an HTML5 application. These two functions have been tested thoroughly and have handled server-side data operations on nearly every jQuery-based HTML5 widget that I have used. 

There may be something in the CF world that is a little more modern than this, however, I have written these functions to handle all of the common use cases that I have found when preparing JSON data. For example, some widgets want a data handle in the JSON, while others don't. These functions have handled all use cases that I have thrown at them when using Kendo UI and have handled other HTML5 libraries, such as jsGrid. I have tested a dozen different similar functions and this approach offered the best performance.

I am also using this component extensively in my how-to ColdFusion and Kendo blog series. If you are working with Kendo UI while reading this series, please download this component.


Download the CFJson Component from GitHub

This component can be found on GitHub at https://github.com/GregoryAlexander77/CfJson. It has been tested on ColdFusion 10 all the way through the most modern ColdFusion version, CF2021.


Working with ColdFusion Queries

When dealing with a native ColdFusion query object, use the convertCfQuery2JsonStruct function to convert it into JSON. This function takes a native ColdFusion query object and converts it into JSON.

There are several arguments, the queryObj is required, and the rest of the arguments are optional. 


Function Arguments

  • queryObj (required)
    Pass in the name of the ColdFusion query. This must be a ColdFusion query object.

  • contentType 
    Default value: json
    This argument, for now, is always set to json. This argument was put into the function as eventually, I hope to add JSONP support. 

  • includeDataHandleName
    Default value: false
    This inserts a data handle in front of the JSON. It is used for special use cases when using the Kendo widgets, and also is used for other HTML libraries, such as jsGrid.

  • dataHandleName
    Default value: false
    Specify your data handle name when setting the includeDataHandle argument to true.

  • includeTotal 
    Default value: false
    Used for the Kendo Grids and for Pagination.

  • overRideTotal
    Default value: false
    Used for pagination when filtering records in a Kendo Grid. 
  • newTotal
    Default value: false
    Used to indicate the total number of records after applying filters to a Kendo Grid. 

  • removeStringHtmlFormatting
    Default value: false
    Removes HTML and special characters in the JSON. This is used to create a sanitized string that is displayed in a grid (works with both Kendo and jsGrid grids)

  • columnThatContainsHtmlStrings
    default value: empty string
    When removeStringHtmlFormatting is set to true, specify the column that you want to be sanitized.

  • convertColumnNamesToLowerCase
    Default value: empty string
    This argument is rarely used. In certain situations, you may want to force all of the JSON element names to a lower case to avoid any case sensitivity issues.

Example ColdFusion Query

Here is a simple query that grabs the Galaxie Blog built-in roles. Here we are getting the role Id, name, and description and output this to JSON to populate our HTML5 widgets.

After obtaining the data, we will pass the name of this query, Data, to the convertCfQuery2JsonStruct method to convert this ColdFusion query into a JSON string. This query will be used for all of the examples below using the convertCfQuery2JsonStruct method that converts a ColdFusion query object into a JSON object.

Note: I am only getting the top two records to make it easier to view the JSON output below.

<!--- Make the query --->
<cfquery name="Data" datasource="#dsn#">
	SELECT TOP 2 RoleId
			,RoleName
			,Description
		FROM Role
</cfquery>

Common Usage Using Default Settings

This takes the ColdFusion query object that we just made, in this case, "Data", and it converts it into JSON without a total, data handle or any special formatting.

This particular usage supports most of the Kendo Widgets, other than the Kendo Grid or other specialized use cases. All of the other arguments are set at default and are not used. 

<!--- Convert the query object into JSON using the default parameters of convertCfQuery2JsonStruct method --->
<cfinvoke component="#application.cfJsonComponentPath#" method="convertCfQuery2JsonStruct" returnvariable="jsonString" >
	<cfinvokeargument name="queryObj" value="#Data#">
</cfinvoke>

This is what the JSON that the function returns when using the default arguments:

[
   {
      "Description":"All functionality.",
      "RoleId":1,
      "RoleName":"Administrator"
   },
   {
      "Description":"Can create and edit their own posts.",
      "RoleId":2,
      "RoleName":"Author"
   }
]

Getting the JSON with a Data Handle

If you need to use a data handle, use the following arguments:

<!--- Convert the query object into JSON --->
<cfinvoke component="cfJson" method="convertCfQuery2JsonStruct" returnvariable="jsonString" >
	<cfinvokeargument name="queryObj" value="#Data#">
	<cfinvokeargument name="contentType" value="json">
	<cfinvokeargument name="includeTotal" value="false">
	<!--- Don't include the data handle for Kendo grids ---> 
	<cfinvokeargument name="includeDataHandle" value="true">
	<cfinvokeargument name="dataHandleName" value="myData">
	<!--- Set to true to force the column names into lower case. --->
	<cfinvokeargument name="convertColumnNamesToLowerCase" value="false">
</cfinvoke>

Using this Function with a ColdFusion ORM Array

This component also works when using ColdFusion ORM. When you query a database using ColdFusion ORM using the map keyword in the query, the object returned is typically an object in an array of structures. 


Function Output

Here is what the function returns:

[ 
   {
      "blogurl":"https://www.gregoryalexander.com/blog/",
      "blogdescription":"A technical blog powered by Galaxie Blog - the most beautiful and functional open source ColdFusion/Kendo UI based blog in the world.",
      "blog":"Gregory's Blog"
   }
]

I will cover the other less common use cases in future blog posts as needed when I discuss the Kendo UI widgets.


Further Reading

This entry was posted on July 12, 2022 at 11:40 PM and has received 741 views.