Gregory's Blog

Galaxie Blog 3 is Now Released  


I am proud to announce that Galaxie Blog 3 is finally released. It was our goal to build one of the most comprehensive HTML5-based blogging platforms that meets or exceeds the out-of-the-box core blogging functionality of major platforms like WordPress. Take a look and see- with Galaxie Blog 3, I think that you will also agree that we delivered on that goal. 

What is Galaxie Blog?

Galaxie Blog is one of the most full-featured out-of-the-box blogging platforms in the world. 

Galaxie Blog was developed with a mobile-first priority. We have put great emphasis on perfecting your mobile experience where you can manage the blog and create a stunning blog post with just a tablet or a phone. 

It is a beautiful HTML5 web application that has extensive media support and will take the media that you upload and create new media formatted to the major social media platforms like Facebook and Twitter. Galaxie Blog has scores of WYSIWYG editors. You don't need to know any HTML in order to create a beautiful blog post. These interfaces will allow you to upload images, videos, and image galleries, and even create maps and map routes. Galaxie Blog is also perfect for the travel blogger- it offers comprehensive tools to generate and share various types of maps that are free of charge. 

Galaxie Blog is eminently themeable. The blog has nearly 30 different pre-built themes and you can develop your own theme within a few minutes and unique fonts can be applied to any theme. 

Galaxie Blog has extensive SEO features to improve your ranking with the search engines. It also automatically structures your blog data for the search engines using the most modern version of JSON-LD. Galaxie Blog also automatically generates RSS that allows other applications to access your blog posts and create real-time feeds.

Galaxie Blog supports multiple users and user capabilities. There are 9 different user roles and dozens of unique capabilities. You can create new custom roles with unique capabilities. For example, you may assign one user to moderate the blog comments, and another to edit the contents of a post. 

Galaxie Blog supports more databases than any other major blog software and can be used with any modern database

Galaxie Blog can be hosted on any ColdFusion-based server and has an automatic installer that will guide you through the installation process. Typical ColdFusion hosting plans start at 11 per month. 

Why Galaxie Blog?

The other blog software, such as WordPress, offers a vast array of features. However, the choices that you have to make to set up a blog are often quite bewildering. 

The majority of the other blogging systems have what is called a freemium business model. This model provides basic blogging features at no cost but charges a premium for additional or advanced features. Every advanced feature set needs to be researched and purchased separately. Often, you may not be aware that these features are missing until they are needed and you may have to resort to making multiple complex ad-hoc purchases. There are also tens of thousands of proprietary themes, each one produced by different developers, and not all of them are safe or legitimate. Without trial and error, it is impossible to determine if the desired plugins that you have chosen will seamlessly work with your themes.

Galaxie Blog is different. This blog can't offer the breadth of choice that other blogging systems such as WordPress offer, however, everything is tightly integrated and everything will seamlessly work together. Galaxie Blog already has most of these freemium features that require additional purchases built-in. For example, Galaxie Blog has nearly every TinyMCE open-source plugin built-in. There are hundreds of features here from embedding programmatic code to having hundreds of silly emoticons that you can embed in a post. We also have added TinyMCE freemium features.  Galaxie Blog also supports rich image and media support along with the ability to auto-generate a table of contents which now requires an $80 TinyDrive subscription. Additionally, we have added other advanced features such as embedding static maps, maps that display the route between two or more locations, and rich gallery support. Other major freemium features include rendering your images for a perfect social media preview, advanced SEO tools that generate JSON to include rich Google media snippets to your google search results, and branded emails that go out to your user subscription base, and more. All of these freemium features are included for free.

Galaxie Blog has scores of open-source libraries, however, each library has been carefully integrated into Galaxie Blog and will work with all of our themes. For example, the buttons on your videos will take on the primary color of your selected theme. If you embed a map route, the route shown will also take on the primary color of the theme. in fact, nearly every Galaxie Blog widget will is tailored to your selected theme! You're not going to find this tight level of integration in a different blogging system.

Experience Galaxie Blog Yourself

If you want to experience Galaxie Blog yourself, please contact me, provide your full name and email address, and I will set up a free account for you.  I won't give you a sales pitch or bug you, but you can investigate the blog's administrative interfaces yourself. I am requiring an initial contact as I don't want to manage spam and adult content. 

Contact me if you're having any issues with the Galaxie Blog installation. I will try to help you free of charge. I may not be able to help you in all situations, but I will try to respond to you as soon as possible. It is important for me to try to support you.

If you are impressed with this blog, please consider going to my GitHub site and starring this repository. I have spent thousands of hours developing this over the last four years, and it means a lot to me to know that you appreciate my contribution to the open-source community.

Happy Blogging!

This entry was posted on June 9, 2022 at 1:12 PM and has received 432 views.

A Comprehensive Look at the Kendo Window


What are the Benefits of a Windowing Interface?

The main benefit of a window-based interface is that it allows the users to perform multiple tasks at the same time. In a web-based interface, you have can have many web interfaces (or applications) in multiple windows. For example, in the Galaxie Blog administrative interface, every post editor has its own window that is launched by clicking on a list of posts in an HTML5 grid interface. Nearly every single administrative interface opens up in a window. Having different information available in multiple windows has several advantages, for example, you can copy the content from one post to another or research the current post that you are creating by looking at prior posts. Once you're done with the research, all of the windows that you opened can be minimized and shoved out of the way to maximize your working space. 

Windows Conserve Working Space

Every window can be configured programmatically to take up a certain size. The windows can be minimized, resized, moved around the screen, refreshed, and closed. One effective design is to use an HTML5 grid, such as Kendo UI Grid, that opens a new window displaying the details when they click on a row within the grid. This design allows your users to open multiple windows and compare the details of the windows side by side.

Windows are Aware of the Current Application State

If you're using a server-side language, such as ColdFusion, the window content can be state-aware when the window opens. This allows you to generate state-aware content on the fly without having to reload the entire page. 

To illustrate, in Galaxie Blog, in order to properly render the UI elements for Apple tablets, I capture the user's screen size using Javascript when the user first hits the blog page. However, since the DOM was loaded at the same time that the cookie was set, I typically don't have access to this information. However, a window will have access to this information as it is initialized after the DOM is loaded and we can adjust the window size to match the client's end device.


What are the Disadvantages of a Web-based Window?

Potential SEO Issues 

Depending upon the structure of your content, Google may not index the window as the content may not be initially loaded into the DOM. Google may also penalize your window if it is constantly popping up on the page. If you use a window, especially if it is modal, be careful to load it as needed otherwise the window will be considered intrusive and you may be penalized. 

Without a Custom Listener, the Window Lacks a URL

A URL is useful for SEO purposes and allows the users to open the content using a memorizable link. However, windows typically use javascript functions to open unless you create a listener on the server side to translate the javascript function to a URL.

In this article, I will show you how to overcome this issue by creating a custom listener.

Note: these same disadvantages also apply to web overlays, popups, and modal windows.


Introducing the Kendo Window 

The Kendo Window has multiple configuration options. You can set the minimum and maximum height and width, title, set the initial window position, determine what user actions are available, add animations, and a host of other options. We will briefly cover these options below.


Implementing the Kendo Window on the Client Side

There are plenty of how-to examples to implement a Kendo Window on the Telerik site, but the basic code examples on the Telerik site are missing some key details. I will share some of my working code using JavaScript along with some tips and tricks that you can use to optimize the code.

Once we are done walking through the code, we will discuss how to implement dynamic window content with server-side code and provide examples.

Client Side Code

If you want to see the Kendo in action while we are walking through the code, click on the button below. This is not necessary as we will share the full code below, but it will allow you to view the full client-side code side by side while we review the individual parts of the code.

Here is the full client-side code. We will walk through the important elements of the code below.

// About window -----------------------------------------------------------------------------------------------
function createAboutWindow(Id) {

	// Remove the window if it already exists
	if ($("#aboutWindow").length > 0) {
		$("#aboutWindow").parent().remove();
	}

	// Set the window title
	if (Id == 1){
		var windowTitle = "About <cfoutput>#htmlEditFormat(application.blog.getProperty('blogTitle'))#</cfoutput>";
	} else if (Id == 2){
		var windowTitle = "About Gregory Alexander";//TODO put in an owner name in the admin section.
	} else if (Id == 3){
		var windowTitle = "Download Galaxie Blog";
	}

	// Typically we would use a div outside of the script to attach the window to, however, since this is inside of a function call, we are going to dynamically create a div via the append js method. If we were to use a div outside of this script, lets say underneath the 'mainBlog' container, it would cause wierd problems, such as the page disappearing behind the window.
	$(document.body).append('<div id="aboutWindow"></div>');
	$('#aboutWindow').kendoWindow({
		title: windowTitle,
		// The window can't be set to full screen per design.
		actions: [<cfoutput>#kendoWindowIcons#</cfoutput>],
		modal: false,
		resizable: true,
		draggable: true,
		// For desktop, we are subtracting 5% off of the content width setting found near the top of this template. These are custom JavaScript functions that determine the clients screen width
		width: <cfif session.isMobile>getContentWidthPercent()<cfelse>(getContentWidthPercentAsInt()-5 + '%')</cfif>,
		height: '85%',// We must leave room if the user wants to select a bunch of categories.
		iframe: false, // don't  use iframes unless it is content derived outside of your own site. 
		content: "<cfoutput>#application.baseUrl#</cfoutput>/about.cfm?aboutWhat=" + Id,// Make sure to create an absolute path here. I had problems with a cached index.cfm page being inserted into the Kendo window probably due to the blogCfc caching logic. 
	<cfif session.isMobile>
		animation: {
			close: {
				effects: "slideIn:right",
				reverse: true,
				duration: 500
			},
		}
	<cfelse>
		close: function() {
			$('#aboutWindow').kendoWindow('destroy');
		}
	</cfif>
	}).data('kendoWindow').center();// Center the window.

}//..function createAboutWindow(Id) {

Create a JavaScript Function to Send Arguments and Open up the Kendo Window

I typically create a JavaScript function to enable multiple windows and create a dynamic ColdFusion template on the server-side to allow the window logic to be reused. I am passing in an Id in order to set window properties. I will also be using this Id on the server-side with ColdFusion to determine which content to show.

function createAboutWindow(Id) {

Destroy All Prior Instances of the Kendo Window

The following Javascript to destroy an existing window is not found in the basic Telerik tutorials. The name of the Kendo window must be entered- here the name is 'aboutWindow'.

This logic is critical to allow you to use multiple Kendo windows- you will have a lot of problems if you don't include the logic to destroy current windows when using multiple Kendo windows.

// Remove the window if it already exists
if ($("#aboutWindow").length > 0) {
	$("#aboutWindow").parent().remove();
}

Set the Kendo Window Properties by the Id that was Passed In

To reuse the same code for multiple windows, dynamically set the window properties by the Id.

// Set the window title
if (Id == 1){
	var windowTitle = "About <cfoutput>#htmlEditFormat(application.blog.getProperty('blogTitle'))#</cfoutput>";
} else if (Id == 2){
	var windowTitle = "About Gregory Alexander";//TODO put in an owner name in the admin section.
} else if (Id == 3){
	var windowTitle = "Download Galaxie Blog";
}

Append the Window Container Div to the Body 

Here we are dynamically appending the div as the container for the new Kendo window. This particular technique is important as it prevents bugs from occurring when having multiple windows. It also eliminates the necessity of having to manually insert the div into your code.

// Typically we would use a div outside of the script to attach the window to, however, since this is inside of a function call, we are going to dynamically create a div via the append js method. If we were to use a div outside of this script, lets say underneath the 'mainBlog' container, it would cause wierd problems, such as the page disappearing behind the window.
$(document.body).append('<div id="aboutWindow"></div>');

Initialize the Kendo Window and Set the User Action Properties

The window initialization occurs in the first line of the code below.

$('#aboutWindow').kendoWindow({

The kendoWindowActions ColdFusion variable is used to set the default user actions for the window. These actions determine what the end-user is able to do with the window using window controls to the right of the window title. The available actions are:

  • Pin
  • Refresh
  • Maximize
  • Minimize
  • Close

I personally don't use the Pin action as I found that it can be a bit buggy. I am also not allowing the user to maximize this particular window due to personal design considerations.

// The about window can't be set to full screen per design.
actions: [<cfoutput>#kendoWindowIcons#</cfoutput>],

Set the Kendo Window Content

Enter the URL of the content template that you want to use in the content var. The URL must return HTML or JSON. Notice that we are also appending the 'aboutWhat 'URL parameter to the URL and passing the Id. This allows us to reuse the about window for various purposes using server-side code.

content: "<cfoutput>#application.baseUrl#</cfoutput>/about.cfm?aboutWhat=" + Id,// Make sure to create an absolute path here. I had problems with a cached index.cfm page being inserted into the Kendo window probably due to the blogCfc caching logic. 

Closing the Kendo Window

On mobile clients, to add some interest, we will subtly slide the window from the left of the screen when we open a window. Similarly, when the window is closed we will reverse the slide-in animation effect. On desktop clients, we will simply destroy the window on the close event. I will cover animation effects in greater detail in a future post.

<cfif session.isMobile>
	animation: {
		close: {
			effects: "slideIn:right",
			reverse: true,
			duration: 500
		},
	}
<cfelse>
	close: function() {
		$('#aboutWindow').kendoWindow('destroy');
	}
</cfif>

Center the Kendo Window

Finally, center the window when it is opened

}).data('kendoWindow').center();// Center the window.

Kendo Window Logic on the Server Side

We will use the Id that we passed in the URL to dynamically generate the content of the window on the server.

On the server side, we will use a conditional if or a switch statement that uses the URL.Id to dynamically generate window content. You can see this code in action by clicking on the about menu at the top of this web page.

Here is a summary example of the about.cfm template code:

<cfif URL.aboutWhat eq 1>
     About Gregory's Blog...
<cfelseif URL.aboutWhat eq 2>
     About Gregory Alexander...
<cfelseif URL.aboutWhat eq 3>
     Download Galaxie Blog...
</cfif>

I won't go into further detail as most of this blog readers are already familiar with server-side code.


Using HTML to Open the Window

To open the window, simply use a link or button that opens the function like so:

<!-- Using an href tag -->
<a href="javascript:createAboutWindow(1)">About Gregory's Blog</a>
<!-- Button example -->
<button id="about1" name="about1" class="k-button k-primary" onclick="javascript:createAboutWindow(1);"><span class="fa-solid fa-up-right-from-square fa-2xs"></span> About Gregory's Blog</button>

Using Server-Side Logic to Create a Listener to Open the Window with a URL

One of the disadvantages to the Kendo window is that you typically can't open it with a friendly URL. This may have negative implications for SEO and it is hard for your users to memorize an important link that opens up content within a window.

However, you can use server-side logic to create a listener that will invoke the JavasScript function via a URL. There are multiple ways to achieve this, but this is a simple implementation that I use with ColdFusion to open a window using a friendly URL.

<script>
<cfif isDefined("URL.about")>
	createAboutWindow(1);
</cfif>
</script>

After the page completely loads, the URL https://www.gregoryalexander.com/blog?about will open up the 'About Gregory's Blog' Kendo window.


Real-World Examples Using this Code


Further Reading

This entry was posted on July 15, 2022 at 12:53 AM and has received 70 views.

Using ColdFusion to Populate Kendo UI Widgets


Table of Contents

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 creating 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. 


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 94 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 128 views.

Incorporate Kendo UI into a ColdFusion Application


Determine if you want to use Kendo jQuery or Kendo Core

If you don't already own a Kendo license, you first need to determine which Kendo UI version you want to use. I have covered the different versions along with the licensing models here.

In a nutshell, if you have a large set of data that you want to share and need the power of the Kendo UI grids, you will need a professional license for Kendo for jQuery. If you don't want to spend money and are mainly interested in adding cool HTML5 widgets to an existing page or want to open source your project, go with Kendo Core. You also can use the professional Kendo for jQuery for 30 days if you want to investigate Kendo UI.

I will cover both versions in this article.

Download the Kendo UI software or use the CDN

There is a debate in the developer community regarding using self-hosting your libraries or using a Content Delivery Network (CDN).

Using a CDN is generally preferred if you have a large website with users from a wide variety of different locations. It is commonly accepted that you don't need a CDN if you have a website with the majority of users from one location or a website that will not generate a lot of traffic, such as a site running on a local intranet.

I am not going to wade into the details of this argument more but there is another important concern to consider if you want to use Kendo Core.

In the past, Telerik, the former company that provided Kendo, completely scrubbed their previous open-source version of Kendo UI. Unlike the current Kendo Core version, the former open-source Kendo version, Kendo UI Web Open Source, had support for the immensely popular Kendo UI grids. Telerik made a business decision to rebrand the new Kendo UI open source as Kendo Core and removed support for the grids and a lot of other widgets. In a matter of days, it was nearly impossible to find this open-source software anymore.

My ColdFusion readers can probably relate and remember when Mura, a popular open-source CMS, suddenly eliminated all of its open-source packages from the net.

If you decide to use the CDN to host Kendo Core, be sure to download the latest version and store it as a backup. You may need it if the CDN suddenly no longer supports Kendo Core.

Kendo Professional for jQuery Recommended Sources

Kendo Core Recommended Sources

jQuery Version Support

If you are using Kendo Professional, please check the Telerik site regarding official jQuery support for the version that you are using at https://docs.telerik.com/kendo-ui/intro/supporting/jquery-support. However, take Teliriks default recommendations with a grain of salt.

I have noticed that the default versions that Telerik recommends are quite old and have some known security issues. Most of the modern Kendo UI Professional versions support jQuery 3.5.1 and this version of jQuery is secure and quite stable when using Kendo.

jQuery is already included in the professional installation packages, so if you are already on a fast and secure private intranet, you can use the included default jQuery library from your installation, however, I would still consider upgrading your jQuery to 3.5.1.  

If you are using Kendo Core, I recommend using jQuery 3.4.1. I have tested scores of jQuery versions with Kendo Core and v3.4.1 is the latest version that I could get working with Kendo Core. This is the jQuery version that I am using here with Galaxie Blog.

jQuery Recommended Sources

When it comes to the CDN argument, jQuery is a completely different beast than Kendo UI or any other software. jQuery is hosted on Google's Hosted Libraries CDN which is one of the fastest and most geographically diverse content delivery networks in the world. Since jQuery is one of the most widely used software libraries with over 75% of the websites using it, your end-users likely already have a primed jQuery cached in their browsers from Google's network. Here I would strongly recommend using Google's CDN when incorporating jQuery, it will be the fastest way to deliver jQuery to the client devices,  however, the choice is yours.

Add the required libraries on a web page

Once you have the required libraries in place, it is time to use them on a web page. When using Kendo UI for jQuery, this process is identical for all the web languages, whether it's PHP or ColdFusion.

  1. If you're self-hosting, upload Kendo UI and jQuery to your web server
  2. Use <!DOCTYPE html> in the very first line of the code. This will inform the browser that this page should be rendered as an HTML5 page.
  3. Include Kendo UI Javascript and CSS files into the head tag of your file
    1. jQuery needs to be loaded before the Kendo UI script
    2. Place the common base Kendo UI stylesheet before the theme stylesheet.

Kendo UI Professional Code Examples

Here is a sample if you are self-hosting and using the default Kendo Professional scripts:

<!DOCTYPE html>
<head>
<!-- Load jQuery from the default Kendo installation, though you should consider using Google's CDN instead. -->
<script src="/common/libs/kendo/js/jquery.min.js"></script>
<!-- Load Kendo -->
<script src="/common/libs/kendo/js/kendo.all.min.js"></script>
<link href="/common/libs/kendo/styles/kendo.common.min.css" rel="stylesheet">
<!-- Load the Kendo theme style. -->
<link href=" /common/libs/kendo/styles/kendo.metro.min.css" rel="stylesheet">
</head>

Here is an example if you want to use one of the CDNs:

<!DOCTYPE html>
<head>
<!-- Load jQuery from Googles CDN -->
<script
	  src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"
	  crossorigin="anonymous"></script>
<!-- Load Kendo UI -->
<script src="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/js/kendo.all.min.js"></script>
<!-- Load the stylesheets -->
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.default.min.css" rel="stylesheet" />
</head>

Kendo Core Code Examples

Self Hosted

<!DOCTYPE html>
<head>
<!-- Load jQuery from Googles CDN -->
<script
	  src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"
	  crossorigin="anonymous"></script>
<!-- Load Kendo UI -->
<script src="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/js/kendo.ui.core.min.js"></script>
<!-- Load the stylesheets -->
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.common.min.css" rel="stylesheet" />
<!-- Load the theme styles -->
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.default.min.css" rel="stylesheet" />
</head>

Kendo Core example from CDN

<!DOCTYPE html>
<head>
<!-- Load jQuery from Googles CDN -->
<script
	  src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"
	  crossorigin="anonymous"></script>
<!-- Load Kendo Core from jsdeliver.net -->
<script src="https://cdn.jsdelivr.net/npm/kendo-ui-core@2022.2.621/js/kendo.ui.core.min.js"></script>
<!-- Load the stylesheets from a local source -->
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.common.min.css" rel="stylesheet" />
<!-- Load the theme styles -->
<link href="http://kendo.cdn.telerik.com/<cfoutput>#kendoVersion#</cfoutput>/styles/kendo.default.min.css" rel="stylesheet" />
</head>

Lazy Loading Kendo UI

To optimize the time that it takes to load your page, you can also defer these Kendo scripts.

Please see my blog article at https://www.gregoryalexander.com/blog/2019/9/9/How-to-speed-up-your-site-with-lazy-loading

Further Information

This entry was posted on July 10, 2022 at 3:24 PM and has received 90 views.




Footer Logo

Your input and contributions are welcomed!

If you have an idea, BlogCfc based code, or a theme that you have built using this site that you want to share, please contribute by making a post here or share it by contacting us! This community can only thrive if we continue to work together.

Images and Photography:

Gregory Alexander either owns the copyright, or has the rights to use, all images and photographs on the site. If an image is not part of the "Galaxie Blog" open sourced distribution package, and instead is part of a personal blog post or a comment, please contact us and the author of the post or comment to obtain permission if you would like to use a personal image or photograph found on this site.

Credits:

Portions of Galaxie Blog are powered on the server side by BlogCfc, an open source blog developed by Raymond Camden. Revitalizing BlogCfc was a part of my orginal inspiration that prompted me to design this site.

Version:

Galaxie Blog Version 3.0 (Toby's Edition) June 14th 2022 Redwood Drive theme