Converting structkeys to lowercase

As you most probably know when you create a structure and don't quote the keys they are automatically converted to uppercase.


<cfset myStruct = structNew()>
<cfset mystruct.one=1>
<cfset mystruct.two=2>
<cfset mystruct.three=3>

When you dump it out you get:

and when you serialize it to json all the keys are also uppercase. This can be problematic since JS is case sensitive. You could create your structure with lowercase keys then serializeJSON() will maintain the case of your structure, but if you don't have control of the structure itself you need to do something to to convert only the structure keys to lowercase.

As a quick and dirty way of doing this I build a recursive function to do just that. Firstly I ran the structure through SerializeJSON() just in case the structure contained other datatypes that also need to be serialized, I think deserialized the string back into a structure. Make sure you use strict mapping so that the function doesn't try to convert your query back into a query. Then call the recursive function to go through and change all the keys to lowercase.

Here is the function:


    <cffunction name="convertStructToLower" access="public" returntype="struct">
        <cfargument name="st" required="true" type="struct">

        <cfset var aKeys = structKeyArray(st)>
        <cfset var stN = structNew()>
        <cfset var i= 0>
        <cfset var ai= 0>
        <cfloop array="#aKeys#" index="i">
            <cfif isStruct(st[i])>
                <cfset stN['#lCase(i)#'] = convertStructToLower(st[i])>
            <cfelseif isArray(st[i])>
                <cfloop from=1 to="#arraylen(st[i])#" index="ai">
                    <cfif isStruct(st[i][ai])>
                        <cfset st[i][ai] = convertStructToLower(st[i][ai])>
                    <cfelse>
                        <cfset st[i][ai] = st[i][ai]>
                    </cfif>
                </cfloop>
                <cfset stN['#lcase(i)#'] = st[i]>
            <cfelse>
                <cfset stN['#lcase(i)#'] = st[i]>
            </cfif>
        </cfloop>
        <cfreturn stn>
    </cffunction>

As you can see it also handles the case where you have an array of structures inside a structure.

I've tested it with nested structures that contain arrays of structures and it seems to work just fine. Perhaps you will find it useful for any Ajax stuff you are doing.

Happy Coding...

Ask Gary: Spry Tabs

I got an email recently asking me about the little tutorial I wrote some time ago on Spry Tabs with Dynamic Content.

I have been trying to improve my website but the problem I have with Spry Tabs and Dynamic Content is that I don't want the tab to reload every time a user goes back to a previous tab but at the same time when the page loads for the first time I want to take advantage of the click on demand option by only loading the defaults tab. Can you think of a solution. My users scroll between tabs and don't want to lose the search results displayed in each tab.

[More]

SEO & Ajax

How do you provide your customers with the Ajax functionality they want and still optimize the site for search engines?

[More]

jQuery UI's new home

Yesterday JQuery announced that they will be including the previously unreleased jQuery effects suite "Enchant" into jQuery UI.

Additionally jQuery UI can now be found at UI.jQuery.com with a really great UI not surprisingly.

I had to right click on the demo page to be sure I wasn't looking at a Flash scroller. Although quite a few of the demo pages were still showing "Under Construction" place holders (I thought that went out of style in 98?), the demos that are available are really good.

You will also notice the design has a particularly Liferay feel to it, it is after all sponsored by them.

ColdEXT

I got a chance to play around a little bit this evening with ColdEXT. If you don't know what it is, it is a really good custom tag library that for a fair portion of the EXTJS library that is pretty easy to use.

It looks like Justin Carter spent a fair amount of time working on this custom tag library. He has a few examples packed into the zip file as well as on his blog but as of yet is lacking any extensive how-to guides (but most of you shouldn't have too much time figuring it out if you have had any exposure at all to EXT).

[More]

EXT Update Supports Adobe Air

Jack and the team over at Ext JS released an update to their popular Ajax framework. This update was release to provide better support for the newly released Adobe Integrated Runtime (AIR).

The sample application built for AIR using the EXT framework was also subsequently updated and is now available (source included) for download.

You can read more about the amazing Simple Task application on the EXT JS blog.

I took the application for a test drive and I have to say it's pretty damn cool. I especially like ability to drag-n-drop tasks from Outlook to Simple Task.

Liferay to Standardize UI on jQuery

I read an interesting article on the jQuery Blog today about how the lead on the jQuery UI team, Paul Bakaus, has been hired by Liferay inc. to "bring Jquery UI to the next level"

Additionally Paul mentions that Liferay will be standardizing all their products to use jQuery. This tight integration of jQuery by Liferay is sure to catapult jQuery's popularity even more.

This is quite an interesting partnership and will undoubtedly have an impact on the company I work for as well as we have been flip/flopping between ExtJs and jQuery but since we plan on doing a lot more work with Liferay I imagine there will be more a lean towards jQuery.

Filtering CFGrid with CFSelect

A reader asked me yesterday about filtering a CFGrid using a CFSelect. I am quite happy to say that it is dead easy to do using the new CF8 tags. You can also bind your CFGrid to more than one control you just need to handle it with your cffunction.

Take the following grid for example. The grid is bound to a tree control as well as another control. The tree control sends the directory to the geFiles function to return a list of files.

[More]

Caution: Binding to CFC

Mike posted on CF-Talk today asking what was wrong with his bind expression on his cfgrid.

At first I thought that he wasn't building the bind expression correctly as you need to work from the webroot down to where the CFC is located.

[More]

EXT Ajax Grid Part 3

In this post we will begin to dissect the javascript code used to create the EXT Ajax Grid.

In Part 1 I simply introduced you to the Javascript in a complete example without really explaining any of the code.

I will do my best to break it down in to manageable chunks. Starting with setting up the Anonymous function and then going onto setting up of the data store.

Here is the complete Javascript block once again for reference:

[More]

Ext Tree adding a Context Menu

In the previous Ext Tree and Coldfusion Example post we set up an EXT treeview bound to a Coldfusion component.

In this example we will be building upon that example to add a dynamic context menu to our tree. The context menu will be populated by calling a function in a Coldfusion component.

Step 1

The first thing we need to do is include the below snippet of code in the head section of our page, but after the ext-all.js.

[More]

Ext Tree and Coldfusion Example

The EXT tree is, in my opinion, a much better implementation of a dynamic ajax tree than what the yahoo utility toolkit starts out with, and subsequently what Adobe decided to use for the CFTREE tag. Once again I am really amazed at the quality work that Jack and his crew have done. The tree itself is relatively simple to set up as either a static tree or dynamic tree. In the example code I will be showing I have set up the tree to have a lazy loader. This means that I will only be showing the root (and in this case the first set of children) of the tree and each time a node is clicked a call will be made to populate that nodes children.

[More]

Coldfusion UI Tags? No thanks!

I have been experimenting with the new coldfusion UI tags since the pre-release program some time ago and the more I use them the more I realize that some of them just aren't really all that useful, and the others only marginally so.

I think I will probably get some use out of the CFLAYOUT and CFWINDOW tags but to be quite honest if I need a grid or a tree I will most likely skip over the CF implementations and go with the EXTJS tree and grid. They are a heck of a lot more configurable, I have access to all the functionality offered whereas with the CF versions I am limited to the functionality and init config options that they thought would be most useful.

I could, perhaps, finagle my way to getting what I need using the ColdFusion.Grid.getGridObject and ColdFusion.Tree.getTreeObject, but with the grid being Ext and the tree being a Yahoo widget it isn't the easiest thing to do, especially if I know that if I used the grid as it was first of all I would have what I wanted immediately without the hassle.

Don't get me wrong the Adobe team did a good job of providing us developers with easier methods of integrating Ajax into our applications but in the end I will probably end up writing custom tags that will give me the flexibility that I need.

I hope others find these new UI tags more useful than the old ones, which I can honestly say I never used.

EXT Ajax Grid Part 2

This is the second installment of building an Ajax grid using the EXT UI and Coldfusion.

In Part 1 we included the library files and set up the Javascript and HTML to render our Grid with paging.

In this entry we will set up an Ajax wrapper component and a component to populate our grid.

We need an Ajax wrapper component in this example because we are not using Coldfusion 8, the Ajax component will act as an intermediary component to instantiate our component and output the results. We could also use a standard cfm page but I prefer to use a component.

ajaxwrapper.cfc


<cffunction name="getFiles" access="remote" output="yes">
    <cfargument name="start" default="1" required="yes"/>
    <cfargument name="limit" default="10" required="yes"/>
    <cfargument name="sort" default="" required="yes"/>
    <cfargument name="dir" default="" required="yes"/>
    <cfargument name="callback" default="" required="no"/>
<!--- the ext grid sends a 0 for the start by default, the startrow attribute on the cfoutput tag must be greater than 0 so we take care of that here before calling the component.--->        
        <cfif start eq 0>
            <cfset start = 1>
        </cfif>
        <cfset obj = createobject("component","fileExplorer")/>
        <cfset retval = obj.getFilesExt(start,limit,sort,dir,"/dev/crucial")/>
        <cfoutput>#callback##retval#</cfoutput>
        
</cffunction>

[More]

EXT Ajax Grid Part 1

I recently posted an example on using one of the Coldfusion 8 Ajax CFGRID. I also mentioned at the time that it's based upon the GUI Library found at ExtJS.com. Well I thought it would be a good idea to also show an example on how to set up a grid using the library.

In Part one I will introduce you to the front end part, that is the javascript code to set up the grid, as well as what files you need to include in order to get it working. The next part we will go through the Javascript. And then in the final part I will show you how I set up the return data. Since I do not have Coldfusion 8 on my hosting provider we will build then entire thing using Coldfusion 6 or MX tags and functions.

So lets get started....

There are some necessary files you need to include at the top of the page that you want to have the grid on. The files are the base Yahoo utilities file, an yahoo to ext adapter and then the main ext library. Jack recently moved away from dependence on a third party base library and has created his own so in the future we won't need to have the yui-utilities included but the ext base library instead.

If you don't have the base library yet you can get it from the Extjs download area.

Put the code below into the html head of your page making sure to change the paths to where you have your resources.


<!-- these two library's must be included before any others -->
<script type="text/javascript" src="resources/javascript/yui-utilities.js"></script>
<script type="text/javascript" src="resources/javascript/ext-yui-adapter.js"></script>
<!-- the main ext library -->
<script type="text/javascript" src="resources/javascript/ext-all.js"></script>
<!-- this is the main styleshee, it is also broken down into separate stylesheets for each 'widget' -->
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css"/>

The next thing we will do is set up our grid. In the head area of your HTML document drop in the following:

[More]

QueryConvertForGrid date format woes

I have come to realize that the implementation of the Ajax functionality has some limitations in flexibility. Something as simple as specifying the output format of a date in the grid for example is missing.

Let me start from the beginning.

I have a function that does a directory listing lets say for example sake the cfdocs directory under the webroot and then returns the files in JSON format.


{"TOTALROWCOUNT":6,"QUERY":{"COLUMNS":["NAME","SIZE","DIRECTORY","DATELASTMODIFIED"],"DATA":[["copyright.htm",3026,"\\\\cfdocs",
"May, 31 2007 10:23:17"],["dochome.htm",3257,"\\\\cfdocs","May, 31 2007 10:23:17"],["newton.js",2028,"\\\\cfdocs","May, 31 2007 10:23:24"],["newton_ie.css",3360,"\\\\cfdocs","May, 31 2007 10:23:24"],["newton_ns.css",4281,"\\\\cfdocs","May, 31 2007 10:23:24"],["toc.css",244,"\\\\cfdocs","May, 31 2007 10:23:24"],[null,null,null,null],[null,null,null,null],[null,null,null,null],
[null,null,null,null]]}}

Notice the date time format. It's correct, it is returning the correct date and time but I haven't specified anywhere that specific return format, perhaps I only want to return the date in "mm/dd/yyyy" format.

In the flash version of the cfgrid I simply add a mask attribute and specify how I would like it to be displayed. But with the HMTL version I am out of luck, unless I do a work around, but in my opinion I shouldn't have to!

But I did do a work around so that I could have the output format I want. It meant formatting the date in my query of queries like so:


        <cfdirectory action="list" directory="#expandpath('#path#')#" name="files"/>
    <cfquery name="getFiles" dbtype="query">
        select name,size,'#webpath#' as directory ,datelastmodified
        from files
        where type='File'
        <cfif gridsortcolumn neq ''>
        order by #gridsortcolumn# #gridsortdirection#
        </cfif>
    </cfquery>

        <cfset mq = queryNew("name,size,directory,datelastmodified","varchar,integer,varchar,varchar")>
        <cfset i = 0>
        <cfoutput query="getfiles">
                <cfset i = i + 1/>
                <cfset temp = queryAddRow(mq,1)/>
                <cfset temp= querySetCell(mq,"name","#name#",i)/>
                <cfset temp= querySetCell(mq,"size","#size#",i)/>
                <cfset temp= querySetCell(mq,"directory","#directory#",i)/>
                <cfset temp= querySetCell(mq,"datelastmodified","#dateformat(dateLastModified,'short')#",i)/>
        </cfoutput>
<cfreturn queryConvertForGrid(mq,arguments.page,arguments.pageSize)/>

which resulted in the following JSON output from the queryConvertForGrid:


{"TOTALROWCOUNT":6,"QUERY":{"COLUMNS":["NAME","SIZE","DIRECTORY","DATELASTMODIFIED"],"DATA":[["copyright.htm",3026,"\\\\cfdocs","05\/31\/2007"],
["dochome.htm",3257,"\\\\cfdocs","05\/31\/2007"],["newton.js",2028,"\\\\cfdocs","05\/31\/2007"],["newton_ie.css",3360,"\\\\cfdocs","05\/31\/2007"],
["newton_ns.css",4281,"\\\\cfdocs","05\/31\/2007"],["toc.css",244,"\\\\cfdocs","05\/31\/2007"],[null,null,null,null],[null,null,null,null],
[null,null,null,null],[null,null,null,null]]}}

And thats what I wanted to begin with. Is there a way to specify the output format and I just haven't found it yet? Is there a way to manipulate the Grid object with javaScript prior to it being displayed in the browser?

I have already received bad news about having a custom column renderer I wonder what the response will be from adobe this time? Hopefully some good news.

Until then, Happy Coding...

Coldfusion 8 CFGRID Column Renderer Update

Well I got a reply from Adobe's Ashwin Mathew regarding custom renderers for Coldfusion 8 CFGRID tag and it reads:

Sorry, Gary, custom renderers are not available right now, but I will file an enhancement request on your behalf so we can get them in for CF9.

I am a little disappointed to hear this honestly.

It means that I will have to write my sample application as a hybrid of CF8 and EXT to get the look that I want, or perhaps I will just keep the implementation simple and just use what is currently available and perhaps later expand on it to include a fancier EXT Grid.

Coldfusion 8 CFGRID Column Renderer

I started building a small example application using the new Ajax components in Coldfusion 8 beta. I have a grid that is populated with a bind to a CFC.

I want to display an image in one of the columns. With the flash format of the grid this isn't an issue, I just need to create a custom cell renderer using action script and I can have it. I checked the Beta Reference Document as well as the Developer Guide and didn't find anything indicating how I would go about adding a cell renderer to the HTML format GRID.

I know I can do it quite easily with the EXT Grid by specifying a renderer for a column (see below for example code*).


//set up a cell renderer
function renderLastMod(value){
return String.format('{0}', value.dateFormat('M j, Y, g:i a'));
}
//set up another cell renderer
function renderFileType(value){
return String.format('<img src="/images/icons/{0}.jpg"/>',value);
}

var cm = new Ext.grid.ColumnModel([{
header: " ",
dataIndex: 'filetype',
renderer: renderFileType //here I am specifying my cell renderer
},{
header: "File Name",
dataIndex: 'name',
width: 220
},{
id: 'lastmod',
header: "Last Modified",
dataIndex: 'lastModified',
width: 150,
renderer: renderLastMod //here I am specifying my cell renderer
}]);

* Code is not by any stretch a complete example

Does anyone know if Adobe added this functionality or not?

For the time being I will have to switch to creating the grid by hand until I get an answer. I am hoping that it was just not documented or perhaps I have overlooked something somewhere.

I will have to put a post on the Coldfusion 8 forums over at adobe.

I will continue building my sample application as I said will use the EXT grid instead of CFGRID I know it may be defeating the purpose a little bit but I would like to have a good app that will be a useful sample.

Happy Coding...

CFLayout

Two new tags introduced by Coldfusion 8 are the <cflayout> and <cflayoutarea>, which is cflayouts child tag.

As the name suggests these two tags deal with laying out a page, duh! What is interesting about these two tags as with the CFTREE and CFGRID mentioned in earlier posts, is that they remove some of the complexity of creating these user interface pieces. And again CF8 is using the EXTjs UI framework here as well.

You have four layout style options when using the cflayout area tag, those being: border, hbox, vbox and tab. The hbox and vbox options are relatively understood (they layout the child tags either horizontally or vertically) the Border and Tab layout options are a bit more interesting.

[More]

Coldfusion 8's CFTREE tag

Coldfusion 8 introduced support for an HTML tree. With the HTML tree you can build an AJAX driven tree, which means you only need to load the to level nodes at first and all subsequent child nodes and leaves are only loaded when needed. The old requirements of the cftree tag, that being living inside of a cfform still exists.

You set up your tree like so:


<cfoutput>
    <cfform name="myform">
        <cftree name="treeTest" height="400" width="200" format="html">
            <cftreeitem bind="cfc:components.tree.getNodes({cftreeitempath},{cftreeitemvalue})">
        </cftree>
    </cfform>
</cfoutput>

The bind expression, like in my previous post about the cfgrid, is used to bind the creation of the tree elements to the output of a CFC.

[More]

Coldfusion 8 Public Beta

I am really excited about the release of the public beta of Coldfusion 8!

I was fortunate enough to take part in the closed beta testing and the new features that have been included in this release of coldfusion are about as important (in my opinion) as the release from Coldfusion 5 to MX.

A few of the more interesting things are pdf support, new image handling functions, ajax, json, a new cfthread (now this is exciting),an array of new GUI tags based on EXT JS and Yahoo GUI Library: cflayout,cfgrid,cfwindow,cfpod, a new cftree. All of the ajax tags support binding to cfc's as well as javascript functions or to a urls, which means asynchronous data loads.

In my coming entries I will endevor to provide examples of some of the new tags, as well as explore some of the features of Cf8 in more detail.


Powered By Railo

Subscribe

Subscribe via RSS
Follow garyrgilbert on Twitter Follow me on Twitter
Or, Receive daily updates via email.

Tags

adobe air ajax apple cf community cfml coldfusion examples ext flash flex google javascript jquery max2007 max2008 misc open source programming railo software technology ui

Recent Entries

No recent entries.

Blogroll

An Architect's View
CFSilence
Rey Bango
TalkingTree

Wish List

My Amazon.com Wish List