<?xml version="1.0" encoding="utf-8"?>

			<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://web.resource.org/cc/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">

			<channel>
			<title>Cutter&apos;s Crossing</title>
			<link>http://www.cutterscrossing.com/index.cfm</link>
			<description>ColdFusion Development, Life, and Other Stuff</description>
			<language>en-us</language>
			<pubDate>Sat, 19 May 2012 10:37:39 -0400</pubDate>
			<lastBuildDate>Tue, 15 May 2012 07:58:00 -0400</lastBuildDate>
			<generator>BlogCFC</generator>
			<docs>http://blogs.law.harvard.edu/tech/rss</docs>
			<managingEditor>web.admin@cutterscrossing.com</managingEditor>
			<webMaster>web.admin@cutterscrossing.com</webMaster>
			<itunes:subtitle></itunes:subtitle>
			<itunes:summary></itunes:summary>
			<itunes:category text="Technology" />
			<itunes:category text="Technology">
				<itunes:category text="Podcasting" />
			</itunes:category>
			<itunes:category text="Technology">
				<itunes:category text="Tech News" />
			</itunes:category>
			<itunes:keywords></itunes:keywords>
			<itunes:author></itunes:author>
			<itunes:owner>
				<itunes:email>web.admin@cutterscrossing.com</itunes:email>
				<itunes:name></itunes:name>
			</itunes:owner>
			
			<itunes:explicit>no</itunes:explicit>
			
			<item>
				<title>ColdFusion 10 is Now Available</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/5/15/ColdFusion-10-is-Now-Available</link>
				<description>
				
				Adobe has released &lt;a href=&quot;http://www.adobe.com/products/coldfusion-family.html&quot; target=&quot;_blank&quot;&gt;ColdFusion&lt;/a&gt; 10. The engineering team has done a fantastic job putting this release together. Here&apos;s a short list of some of what&apos;s new:

&lt;ul&gt;
    &lt;li&gt;Improved/Updated
        &lt;ul&gt;
            &lt;li&gt;caching&lt;/li&gt;
            &lt;li&gt;ORM&lt;/li&gt;
            &lt;li&gt;webservices&lt;/li&gt;
            &lt;li&gt;scheduler&lt;/li&gt;
            &lt;li&gt;hotfix management&lt;/li&gt;
            &lt;li&gt;security&lt;/li&gt;
            &lt;li&gt;MS Exchange integration&lt;/li&gt;
            &lt;li&gt;security&lt;/li&gt;
            &lt;li&gt;Solr&lt;/li&gt;
            &lt;li&gt;charting (now html 5)&lt;/li&gt;
            &lt;li&gt;Java integration&lt;/li&gt;
            &lt;li&gt;Flex and AIR lazy loading&lt;/li&gt;
            &lt;li&gt;VFS&lt;/li&gt;
            &lt;li&gt;more!&lt;/li&gt;
        &lt;/ul&gt;&lt;/li&gt;
    &lt;li&gt;html 5 support&lt;/li&gt;
    &lt;li&gt;websockets&lt;/li&gt;
    &lt;li&gt;RESTful services&lt;/li&gt;
    &lt;li&gt;greater cfscript parity&lt;/li&gt;
    &lt;li&gt;geo-tagging&lt;/li&gt;
    &lt;li&gt;CFC auto constructors&lt;/li&gt;
    &lt;li&gt;method chaining&lt;/li&gt;
    &lt;li&gt;closures&lt;/li&gt;
    &lt;li&gt;Tomcat (no more JRun)&lt;/li&gt;
    &lt;li&gt;more!&lt;/li&gt;
&lt;ul&gt;

Wow! A lot of changes and additions. The team has been in overdrive, and it all looks spectacular. Download the free Developer&apos;s Edition and start playing.

As a bonus, they also release an update to &lt;a href=&quot;http://www.adobe.com/products/coldfusion-builder.html&quot; target=&quot;_blank&quot;&gt;ColdFusion Builder&lt;/a&gt; as well!
				</description>
				
				<category>Adobe</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Tue, 15 May 2012 07:58:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/5/15/ColdFusion-10-is-Now-Available</guid>
				
				
			</item>
			
			<item>
				<title>CFQueryReader v2.1: Now with metaData support</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/5/9/CFQueryReader-v21-Now-with-metaData-support</link>
				<description>
				
				The &lt;a href=&quot;http://www.sencha.com&quot; target=&quot;_blank&quot;&gt;Sencha&lt;/a&gt; guys just keep upping the bar, and &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS 4.1&lt;/a&gt; is no exception. I&apos;ve been reading &lt;a href=&quot;http://www.google.com/url?sa=t&amp;rct=j&amp;q=loianne%20groner&amp;source=web&amp;cd=1&amp;ved=0CFcQFjAA&amp;url=http%3A%2F%2Floianegroner.com%2F&amp;ei=c1yqT8TFCoeS9gTniejwAQ&amp;usg=AFQjCNFHEfwzMDmN70PtX3h_cGxx2HFKkg&amp;cad=rja&quot; target=&quot;_blank&quot;&gt;Loiane Groner&lt;/a&gt;&apos;s &lt;a href=&quot;http://www.packtpub.com/ext-js-4-first-look/book/mid/100412vj65lg&quot; target=&quot;_blank&quot;&gt;Ext JS 4 First Look&lt;/a&gt;, to review it, and continually find new, cool stuff. 4.1, however, takes it even further. While upgrading &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com&quot;&gt;CFQueryReader&lt;/a&gt;, I was working with 4.1 RC2. And, while extending the base classes, I came across a new feature that wasn&apos;t fully documented yet: adding &lt;em&gt;metaData&lt;/em&gt; to a server-side store response for changing configuration on the fly. Sometimes it would be nice to just...change up. Now that 4.1 is fully released, I had to make sure that this worked in CFQueryReader.

So, last night I sat down and hammered out this functionality. It took a lot more than I realised, and I learned a lot more about the Ext JS internal code, but I think CFQueryReader is better for it. Consider the following ColdFusion method:

&lt;code&gt;
/**
 *	FUNCTION getWithMeta
 *	This function returns the ColdFusion Query object as part of a struct object.
 *
 *	@access remote
 *	@returnType struct
 *	@output false
 */
function getWithMeta(numeric pageIndex = 1, numeric pageSize = 50, string sort = &quot;&quot;, string search = &quot;&quot;) {
	var retVal = {&quot;success&quot; = true, &quot;pageIndex&quot; = ARGUMENTS.pageIndex, &quot;pageCount&quot; = 0, &quot;recordCount&quot; = 0, &quot;message&quot; = &quot;&quot;, &quot;getEntries&quot; = &quot;&quot;, &quot;metaData&quot; = {&quot;root&quot; = &quot;getEntries&quot;, &quot;totalProperty&quot; = &quot;recordCount&quot;, &quot;successProperty&quot; = &quot;success&quot;, &quot;messageProperty&quot; = &quot;message&quot;, &quot;idProperty&quot; = &quot;id&quot;, &quot;fields&quot; = []}};
	StructAppend(LOCAL.retVal, GetEntries(argumentCollection: ARGUMENTS), true);
	var colArr = ListToArray(LOCAL.retVal.getEntries.columnList);
	LOCAL.retVal.metaData.fields = [
		{&quot;name&quot; = &quot;id&quot;, &quot;type&quot; = &quot;string&quot;, &quot;mapping&quot; = JavaCast(&quot;int&quot;,0)},
		{&quot;name&quot; = &quot;title&quot;, &quot;type&quot; = &quot;string&quot;, &quot;mapping&quot; = JavaCast(&quot;int&quot;,3)},
		{&quot;name&quot; = &quot;posted&quot;, &quot;type&quot; = &quot;date&quot;, &quot;mapping&quot; = JavaCast(&quot;int&quot;,2)},
		{&quot;name&quot; = &quot;views&quot;, &quot;type&quot; = &quot;int&quot;, &quot;mapping&quot; = JavaCast(&quot;int&quot;,1)}
	];
	return LOCAL.retVal;
}
&lt;/code&gt;

I reused my &lt;em&gt;getEntries&lt;/em&gt; method, to get my query. Here, I&apos;m creating a &lt;em&gt;metaData&lt;/em&gt; object, at the root of the return, to define the dataset. Configuration options that I normally define client side (root, totalProperty, etc) I put in to the &lt;em&gt;metaData&lt;/em&gt; key. When the response is received by the client, the reader will pass this &lt;em&gt;metaData&lt;/em&gt; in to our app, applying this configuration to our reader, store, model, and so on. In the above method, we let the &lt;em&gt;metaData&lt;/em&gt; &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/5/5/ColdFusion-Query-Column-Order-Did-You-Know&quot;&gt;map our columns to fields&lt;/a&gt;, rather than doing it client side (CFQueryReader will automatically skip the column mapping if &lt;em&gt;metaData.fields&lt;/em&gt; is present in the response.) Our client side store might now look like this:

&lt;code&gt;
Ext.create(&apos;Ext.data.Store&apos;, {
	storeId: &apos;entryStore&apos;,
	model: &apos;Entry&apos;,
	remoteSort: true,
	proxy: {
		type: &apos;ajax&apos;,
		url: &apos;/com/cc/Blog/Entries.cfc&apos;,
		extraParams: {
			returnFormat: &apos;json&apos;,
			method: &apos;getWithMeta&apos;
		},
		limitParam: &apos;pageSize&apos;,
		pageParam: &apos;pageIndex&apos;,
		sortParam: &apos;sort&apos;,
		reader: {
			type: &apos;cfquery&apos;
		}
	},
	autoLoad: true
});
&lt;/code&gt;

A full example of this, in action, can be seen on &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com/index-5.html&quot;&gt;a demo page&lt;/a&gt; of the CFQueryReader site. The full source code, of the example, can be found in the &lt;a href=&quot;https://github.com/cutterbl/CFQueryReader&quot; target=&quot;_blank&quot;&gt;CFQueryReader GitHub repository&lt;/a&gt;.
				</description>
				
				<category>Learning ExtJS</category>
				
				<category>Ajax</category>
				
				<category>ExtJS</category>
				
				<category>CFQueryReader</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Wed, 09 May 2012 10:16:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/5/9/CFQueryReader-v21-Now-with-metaData-support</guid>
				
				
			</item>
			
			<item>
				<title>Ext JS 4.1 Grid: Part1: Basic Config</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/5/7/Ext-JS-41-Grid-Part1-Basic-Config</link>
				<description>
				
				Many moons ago, I wrote a series on &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/My-First-ExtJS-DataGrid&quot;&gt;My First Ext JS Data Grid&lt;/a&gt;. It was very popular. In fact, it got me the gig co-authoring &lt;a href=&quot;http://www.amazon.com/s/ref=ntt_athr_dp_sr_3?_encoding=UTF8&amp;sort=relevancerank&amp;search-alias=books&amp;ie=UTF8&amp;field-author=Steve%20%27Cutter%27%20Blades&quot; target=&quot;_blank&quot;&gt;two books on Ext JS&lt;/a&gt; and spawned an &lt;a href=&quot;https://github.com/cutterbl/CFQueryReader&quot; target=&quot;_blank&quot;&gt;open source project&lt;/a&gt; targeted at integrating &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS&lt;/a&gt; with &lt;a href=&quot;http://www.adobe.com/products/coldfusion&quot; target=&quot;_blank&quot;&gt;ColdFusion&lt;/a&gt;. But, I did that series back in 2007, using Ext JS 1.1 (maybe?), and an update is long overdue.Today I&apos;ll start that update. Well, actually it began almost two weeks back, when &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/4/23/Ext-JS-4-and-ColdFusion-CFQueryReader-20&quot;&gt;I announced the update to CFQueryReader&lt;/a&gt;. In that post, and in the demo code in the GitHub download, I show you how to define a data &lt;a href=&quot;http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Model&quot; target=&quot;_blank&quot;&gt;Model&lt;/a&gt; and a data &lt;a href=&quot;http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Store&quot; target=&quot;_blank&quot;&gt;Store&lt;/a&gt;, using &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com&quot;&gt;CFQueryReader&lt;/a&gt; as a custom data &lt;a href=&quot;http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.reader.Reader&quot; target=&quot;_blank&quot;&gt;Reader&lt;/a&gt;. What isn&apos;t in the post (though it is in the GitHub download), is how easy it is to create a data grid with Ext JS 4.1

&lt;code&gt;
Ext.create(&apos;Ext.grid.Panel&apos;, {
	title: &apos;Testing: getWithMeta (query as part of custom struct)&apos;,
	store: Ext.getStore(&apos;entryStore&apos;),
	renderTo: &apos;demo&apos;,
	columns: [
	    {header: &apos;ID&apos;, dataIndex: &apos;id&apos;},
	    {header: &apos;Title&apos;, dataIndex: &apos;title&apos;},
	    {header: &apos;Posted&apos;, dataIndex: &apos;posted&apos;},
	    {header: &apos;Views&apos;, dataIndex: &apos;views&apos;}
	],
    width: 380,
    height: 600
});
&lt;/code&gt;

The really important pieces here are the &lt;em&gt;store&lt;/em&gt;, &lt;em&gt;renderTo&lt;/em&gt;, and &lt;em&gt;columns&lt;/em&gt; configuration options. The &lt;em&gt;store&lt;/em&gt; references the &lt;em&gt;storeId&lt;/em&gt; of the data store you create to feed the grid. The &lt;em&gt;renderTo&lt;/em&gt; references the id of a div element to render the grid within, on your page. The &lt;em&gt;columns&lt;/em&gt; option defines, in order, the columns to display within the grid. In this configuration we have the minimum information needed: the header title of the column and the data field the column will map to. That&apos;s it! Oh, sure, there&apos;s a lot more you can do: paging bars and column renderers and grouping and stuff. We&apos;ll get into it. But, for now, this is all you need to create a very basic grid in Ext JS 4.1. You can download the demo code from the &lt;a href=&quot;https://github.com/cutterbl/CFQueryReader&quot; target=&quot;_blank&quot;&gt;CFQueryReader GitHub repository&lt;/a&gt;.
				</description>
				
				<category>Learning ExtJS</category>
				
				<category>ExtJS</category>
				
				<category>CFQueryReader</category>
				
				<category>ColdFusion</category>
				
				<category>Development</category>
				
				<category>My First ExtJS DataGrid</category>
				
				<pubDate>Mon, 07 May 2012 23:00:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/5/7/Ext-JS-41-Grid-Part1-Basic-Config</guid>
				
				
			</item>
			
			<item>
				<title>ColdFusion Query Column Order: Did You Know?</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/5/5/ColdFusion-Query-Column-Order-Did-You-Know</link>
				<description>
				
				Now first let me say that I&apos;ve only seen this behavior on ColdFusion 9.01 with Cumulative Hotfix 2. My ColdFusion 10 VM blew up this morning, and I haven&apos;t had 7 or 8 for a while now, so someone else might have to verify this behavior on those platforms for me.

This morning I was testing out a new feature of &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS 4.1&lt;/a&gt;, and ran into something interesting. One of the reasons that I wrote &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com&quot;&gt;CFQueryReader&lt;/a&gt;, as well as &lt;a href=&quot;http://examples.cutterscrossing.com/serializeCFJSON&quot;&gt;serializeCFJSON&lt;/a&gt;, was because of the way that ColdFusion handles it&apos;s JSON conversions of it&apos;s native query object.

&lt;code&gt;
{
	&quot;COLUMNS&quot;:[&quot;ID&quot;,&quot;NAME&quot;,&quot;EMAIL&quot;],
	&quot;DATA&quot;:[
		[1,&quot;Ed Spencer&quot;,&quot;ed@sencha.com&quot;],
		[2,&quot;Abe Elias&quot;,&quot;abe@sencha.com&quot;],
		[3,&quot;Cutter&quot;,&quot;no@address.giv&quot;]
	]
}
&lt;/code&gt;

I&apos;ve written before, about how Adobe&apos;s dataset serialization is much trimmer, but many client-side libraries and plugins expect a more standardized format.

&lt;code&gt;
{
    &quot;users&quot;: [
       {
           &quot;id&quot;: 1,
           &quot;name&quot;: &quot;Ed Spencer&quot;,
           &quot;email&quot;: &quot;ed@sencha.com&quot;
       },
       {
           &quot;id&quot;: 2,
           &quot;name&quot;: &quot;Abe Elias&quot;,
           &quot;email&quot;: &quot;abe@sencha.com&quot;
       }
    ]
}
&lt;/code&gt;

It&apos;s not too difficult for us, client-side, to map the column to the proper data position in the record array. In fact, that&apos;s basically what CFQueryReader and serializeCFJSON both do. But why is it even necessary? Most of these client-side libraries allow us to write mappings in configurations anyway, so why write something else to do it?

Well, there&apos;s two reasons really. First of all, the client-side developer may not have that much insight into the server-side developer&apos;s code (they can be different people), and would probably be unaware of API changes. The second reason? Well, if you&apos;ve used ColdFusion for a while, you might know that there was a time when you could not depend on the column order always being the same. At one point, the columns were returned in alphabetical order. This would make it really hard to figure the position out prior to run time, unless you have intimate knowledge of every change to your API as it happens.

It appears that this isn&apos;t as much of a problem today. Kind of. I&apos;ll run this query:

&lt;code&gt;
LOCAL.sql = &quot;SELECT	SQL_CALC_FOUND_ROWS id,
		views,
		posted,
		title
FROM	tblblogentries
WHERE 0 = 0&quot;;
LOCAL.q = new Query(sql = LOCAL.sql, datasource = VARIABLES.dsn);
LOCAL.retVal.getEntries = LOCAL.q.execute().getResult();
&lt;/code&gt;

If you dump the results to the page, you&apos;ll see the following:

&lt;div style=&quot;text-align:center&quot;&gt;
	&lt;img src=&quot;/images/queryordercfdump-1.png&quot; /&gt;
&lt;/div&gt;

Now, server-side, ever query comes with a variable we can use to reference the columns used in a query. I&apos;ll use ColdFusion&apos;s ArrayToList(LOCAL.q.columnList) method to dump the query&apos;s columnList property to the page:

&lt;div style=&quot;text-align:center&quot;&gt;
	&lt;img src=&quot;/images/queryordercfdump-2.png&quot; /&gt;
&lt;/div&gt;

Look closely and you&apos;ll see that both appear to be in alphabetical order. The query dump and the column list showed them in alphabetical order. That said, we then look at the JSON return:

&lt;div style=&quot;text-align:center&quot;&gt;
	&lt;img src=&quot;/images/queryordercfdump-3.png&quot; /&gt;
&lt;/div&gt;

Wait a minute? Now the columns appear in the same order that they are in the query. That&apos;s a change.Let&apos;s change the column order in the query, and see if it changes anything.

&lt;code&gt;
LOCAL.sql = &quot;SELECT	SQL_CALC_FOUND_ROWS id,
		title,
		posted,
		views
FROM	tblblogentries
WHERE 0 = 0&quot;;
&lt;/code&gt;

&lt;div style=&quot;text-align:center&quot;&gt;
	&lt;img src=&quot;/images/queryordercfdump-4.png&quot; /&gt;
&lt;/div&gt;

Notice that, again, the column order matches that of the order it was used in the query. Running a cfdump of the query, and it&apos;s columnList, still show alphabetical order. Why is it different? Why does this matter? Well, I&apos;m going to show you that in a follow-up post (on Ext JS 4.1 and ColdFusion), but in the mean time it&apos;s a good thing to know, that the JSON returnFormat will give you query column orders identical to that used in the query. And, as I said above, somebody please verify this for me on other versions of the platform.
				</description>
				
				<category>Ajax</category>
				
				<category>ColdFusion</category>
				
				<category>JSON</category>
				
				<pubDate>Sat, 05 May 2012 18:48:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/5/5/ColdFusion-Query-Column-Order-Did-You-Know</guid>
				
				
			</item>
			
			<item>
				<title>JQuery Plugin: serializeCFJSON</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/5/2/JQuery-Plugin-serializeCFJSON</link>
				<description>
				
				Quick note about my &lt;a href=&quot;https://github.com/cutterbl/serializeCFJSON&quot; target=&quot;_blank&quot;&gt;serializeCFJSON&lt;/a&gt; project out on GitHub. I wrote this quick JQuery plugin to convert ColdFusion&apos;s JSON representation of it&apos;s native query objects. ColdFusion represents datasets in a trim manner, as an object containing two arrays: One, an array of column names, and the other, an array of arrays, each representing one record of the set. Most representations of recordsets are an array of objects, each record represented as a collection of name/value pairs. ColdFusion&apos;s representation is much smaller, removing a lot of unnecessary duplication, but many pre-built frameworks and plugins look for the name/value pair objects.

What the plugin does is convert ColdFusion&apos;s representation into the more standard form. Ajax transfer is unaffected, as the trimmer format is still being passed. What we get is some very minor client-side overhead in the creation of a new object. What&apos;s more, the plugin recursively searches through a JSON object and converts any ColdFusion query that it finds. So, if you &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/9/26/How-I-Do-Things-ColdFusion-and-Ajax-Requests&quot;&gt;nest your query inside a larger object&lt;/a&gt;, the plugin will still convert it for you.

I put up a &lt;a href=&quot;http://examples.cutterscrossing.com/serializeCFJSON&quot;&gt;demo&lt;/a&gt; in the Projects menu, at the top of this site. This is a refactor of my &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/4/4/Intro-to-jqGrid-Part-7-Grouping&quot;&gt;Grouped jqGrid&lt;/a&gt; example, using the plugin for the data conversion. The full sample code for the demo can be found in the &lt;a href=&quot;https://github.com/cutterbl/serializeCFJSON&quot; target=&quot;_blank&quot;&gt;GitHub repository&lt;/a&gt;.

Take her out for a spin, and let me know what you think.
				</description>
				
				<category>Ajax</category>
				
				<category>ColdFusion</category>
				
				<category>JQuery</category>
				
				<category>JSON</category>
				
				<category>jqGrid</category>
				
				<pubDate>Wed, 02 May 2012 22:41:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/5/2/JQuery-Plugin-serializeCFJSON</guid>
				
				
			</item>
			
			<item>
				<title>CFQueryReader 2.0: Site and Demo Updates</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/4/26/CFQueryReader-20-Site-and-Demo-Updates</link>
				<description>
				
				&lt;i&gt;Note: I mistakenly posted this under the wrong title. I must get more sleep ;)&lt;/i&gt;

I finally got around to a major overhaul of the &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com&quot;&gt;CFQueryReader site&lt;/a&gt;, including all new demos and documentation of the latest build for Ext JS 4.x.

The new demos for Ext JS 2.x and 3.x include links to legacy API&apos;s for both versions of the library. The 3.x version includes an example of using Ext Direct, and the new 4.x demo includes paging data grids.

(Big thanks to Loiane&apos;s &lt;a href=&quot;http://www.packtpub.com/ext-js-4-first-look/book/mid/100412vj65lg&quot; target=&quot;_blank&quot;&gt;Ext JS 4 First Look&lt;/a&gt;, which showed me very quickly how dead simple Ext JS grids and data stores have become.)

I have not yet tested CFQueryReader with &lt;a href=&quot;http://www.sencha.com/products/touch/&quot; target=&quot;_blank&quot;&gt;Sencha Touch&lt;/a&gt;, but it should work. Any feedback just let me know.
				</description>
				
				<category>Learning ExtJS</category>
				
				<category>ExtJS</category>
				
				<category>CFQueryReader</category>
				
				<category>ColdFusion</category>
				
				<category>Development</category>
				
				<category>My First ExtJS DataGrid</category>
				
				<pubDate>Thu, 26 Apr 2012 01:09:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/4/26/CFQueryReader-20-Site-and-Demo-Updates</guid>
				
				
			</item>
			
			<item>
				<title>Ext JS 4 and ColdFusion: CFQueryReader 2.0</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/4/23/Ext-JS-4-and-ColdFusion-CFQueryReader-20</link>
				<description>
				
				Wow! It&apos;s been too long. I&apos;ve been so buried playing with new stuff I haven&apos;t had much time to write about it. Time to rectify that.

My position over the last year and a half hasn&apos;t required me to use &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS&lt;/a&gt;. And without a  project I really haven&apos;t had much time to dive in to Ext JS 4. But, I am reviewing Loiane&apos;s &lt;a href=&quot;http://www.packtpub.com/ext-js-4-first-look/book/mid/100412vj65lg&quot; target=&quot;_blank&quot;&gt;Ext JS 4 First Look&lt;/a&gt; right now, and decided the simplest way to get in was to apply what she was telling me. I knew some of the basics, but Ext JS 4 is a big change, and Loaine&apos;s book quickly helped me to grok differences in the class model, updates to the data api, and more. In no time at all I had completely rewritten &lt;a href=&quot;http://cfqueryreader.cutterscrossing.com&quot;&gt;CFQueryReader&lt;/a&gt;, for parsing the native JSON return of a ColdFusion query object. I need to verify, but I&apos;m fairly certain there are more lines of comments than there are code, in the new file. And it is wicked simple. First, include the js file, then define a record of data:&lt;code&gt;
	Ext.define(&apos;Artist&apos;, {
		extend: &apos;Ext.data.Model&apos;,
		fields: [
			{name:&apos;city&apos;, type:&apos;string&apos;},
			{name:&apos;state&apos;, type:&apos;string&apos;},
			{name:&apos;postalcode&apos;, type:&apos;string&apos;},
			{name:&apos;email&apos;, type:&apos;string&apos;},
			{name:&apos;phone&apos;, type:&apos;string&apos;},
			{name:&apos;fax&apos;,type:&apos;string&apos;},
			{name:&apos;thepassword&apos;,type:&apos;string&apos;},
			{name:&apos;artistId&apos;, type:&apos;int&apos;},
			{name:&apos;firstName&apos;, type:&apos;string&apos;},
			{name:&apos;lastName&apos;, type:&apos;string&apos;},
			{name:&apos;address&apos;, type:&apos;string&apos;}
		],
		idProperty: &apos;artistId&apos;
	});
&lt;/code&gt;

Then, define your data &apos;Store&apos;:

&lt;code&gt;
	Ext.create(&apos;Ext.data.Store&apos;, {
		model: &apos;Artist&apos;,
		storeId: &apos;artistStore_1&apos;,
		remoteSort: true,
		proxy: {
			type: &apos;ajax&apos;,
			url: &apos;/com/cc/ArtGallery/Artists.cfc&apos;,
			extraParams: {
				method: &apos;GetAllStandard&apos;,
				returnFormat: &apos;json&apos;
			},
			reader: {
				type: &apos;cfquery&apos;
			}
		},
		autoLoad: true
	});
&lt;/code&gt;

That example is for a method that only returns a query. I &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/9/26/How-I-Do-Things-ColdFusion-and-Ajax-Requests&quot;&gt;like to return a struct&lt;/a&gt;, so I also included the ability to reference that:

&lt;code&gt;
	Ext.create(&apos;Ext.data.Store&apos;, {
		model: &apos;Artist&apos;,
		storeId: &apos;artistStore_3&apos;,
		remoteSort: true,
		proxy: {
			type: &apos;ajax&apos;,
			url: &apos;/com/cc/ArtGallery/Artists.cfc&apos;,
			extraParams: {
				method: &apos;getAllInStruct&apos;,
				returnFormat: &apos;json&apos;
			},
			reader: {
				type: &apos;cfquery&apos;,
				query: &apos;getArtists&apos;,
				totalProperty: &apos;totalRowCount&apos;,
				successProperty: &apos;success&apos;,
				messageProperty: &apos;message&apos;
			}
		},
		autoLoad: true
	});
&lt;/code&gt;

It&apos;s really that simple! Go pull CFQueryReader from &lt;a href=&quot;http://cfqueryreader.riaforge.org&quot; target=&quot;_blank&quot;&gt;RIAForge&lt;/a&gt; and test it out against the demo &lt;b&gt;CFArtGallery&lt;/b&gt; datasource included in your CF install.
				</description>
				
				<category>ExtJS</category>
				
				<category>CFQueryReader</category>
				
				<category>ColdFusion</category>
				
				<category>Development</category>
				
				<pubDate>Mon, 23 Apr 2012 16:22:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/4/23/Ext-JS-4-and-ColdFusion-CFQueryReader-20</guid>
				
				
			</item>
			
			<item>
				<title>Intro to jqGrid Part 7: Grouping</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/4/4/Intro-to-jqGrid-Part-7-Grouping</link>
				<description>
				
				OK, I know I said I was done, but I kept playing around and figured I should share. &lt;a href=&quot;http://www.trirand.com/jqgridwiki/doku.php&quot; target=&quot;_blank&quot;&gt;jqGrid&lt;/a&gt;, like other (read: &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS&lt;/a&gt;) good grid implementations, has the ability to &lt;em&gt;group&lt;/em&gt; your data. What does that mean exactly? Well, let&apos;s look at our demo for inspiration. We&apos;ve created a grid of blog post entries. Entries have associated &lt;em&gt;Categories&lt;/em&gt;. We can reconfigure our grid to show the entries grouped by Category, with Category headers and accordion like separation.Accomplishing this is fairly easy, taking a combination of jqGrid configuration, and changes to our data retrieval process. First we&apos;ll look at our configuration. We need two new config attributes: &lt;em&gt;grouping&lt;/em&gt; and &lt;em&gt;groupingView&lt;/em&gt;.

&lt;h4&gt;jqGridDemo.js - Grid Configuration&lt;/h4&gt;
&lt;code&gt;
grid.jqGrid({
	...
	sortname: &apos;Posted&apos;,
	sortorder: &apos;asc&apos;,
	postData:{method:&quot;GetGroupedEntries&quot;,returnFormat:&quot;JSON&quot;},
	grouping: true,
	groupingView: {
		groupField: [&apos;categoryName&apos;],
		groupDataSorted: true
	},
	...
});
&lt;/code&gt;

Simple enough. We said &quot;Yes, we want a grouping grid&quot;, and then told it which column to group on. &quot;Why is the &lt;em&gt;groupField&lt;/em&gt; an array?&quot; Good question. The writers of jqGrid are planning to support multiple grouping levels in the future, and will use this array form to define multiple columns at that time. Since jqGrid can only take one column right now, just place that top level grouping column. We also set &lt;em&gt;groupDataSorted&lt;/em&gt; to &lt;em&gt;true&lt;/em&gt;, so that it will pass the &lt;em&gt;groupField&lt;/em&gt; column name as part of the &lt;em&gt;sortCol&lt;/em&gt; argument on server-side requests. This means that all server-side requests will now have a &lt;em&gt;sortCol&lt;/em&gt; in the form of &lt;b&gt;{groupField} asc, {sortCol}&lt;/b&gt;. The need for this will become apparent when we adjust our paging query. Let&apos;s look at that next. You&apos;ll notice I adjusted the &lt;em&gt;postData&lt;/em&gt; attribute, and changed the name of the method we&apos;ll call. I also changed our initial sorting column and direction.

In our &lt;em&gt;Entries.cfc&lt;/em&gt;, let&apos;s copy our &lt;em&gt;GetEntries&lt;/em&gt; method, paste it again, and rename the new one to &lt;em&gt;GetGroupedEntries&lt;/em&gt;. From there, let&apos;s start off by looking at our query. We&apos;ve never pulled the Categories before, so now we need to adjust to pull in the necessary information. Because there can be multiple categories assigned to an entry, &lt;a href=&quot;http://www.blogcfc.com/index.cfm&quot; target=&quot;_blank&quot;&gt;BlogCFC&lt;/a&gt; uses a mapping table, &lt;em&gt;tblblogentriescategories&lt;/em&gt;, to link entries (&lt;em&gt;tblblogentries&lt;/em&gt;) to categories (&lt;em&gt;tblblogcategories&lt;/em&gt;). By adding some &lt;em&gt;JOIN&lt;/em&gt; statements, and table aliases, we can now add our column to the query.

&lt;h4&gt;Entries.cfc - GetGroupedEntries Query&lt;/h4&gt;
&lt;code&gt;
LOCAL.sql = &quot;SELECT	SQL_CALC_FOUND_ROWS b.id,
				b.title,
				c.categoryname,
				b.posted,
				b.views
			FROM	tblblogentries b
			INNER JOIN tblblogentriescategories bec ON bec.entryidfk = b.id
			INNER JOIN tblblogcategories c ON c.categoryid = bec.categoryidfk
			WHERE 0 = 0
			 &quot;;
&lt;/code&gt;

Then we&apos;re required to have our records grouped by category. This is why jqGrid adjusted the &lt;em&gt;sortCol&lt;/em&gt; variable, because we need to add the &lt;em&gt;groupField&lt;/em&gt; to our &lt;em&gt;ORDER BY&lt;/em&gt; clause. You&apos;ll recall, though, that we had a bit of code to verify the validity of our &lt;em&gt;sortCol&lt;/em&gt; variable. We&apos;ll need to adjust this first, or it will throw an error.

&lt;h4&gt;Entries.cfc - GetGroupedEntries: Set ORDER BY&lt;/h4&gt;
&lt;code&gt;
LOCAL.scArr = ListToArray(ARGUMENTS.sortCol);
LOCAL.sortCol = (ArrayLen(LOCAL.scArr) eq 2) ? LOCAL.scArr[2] : ARGUMENTS.sortCol;
// Verify that your sort column and direction are valid. If not, then return an error.
if(ArrayFindNoCase(VARIABLES._COLUMNARRAY, Trim(LOCAL.sortCol)) AND ArrayFindNoCase(VARIABLES._DIRARRAY, ARGUMENTS.sortDir)){
	LOCAL.orderby = ARGUMENTS.sortCol &amp; &quot; &quot; &amp; ARGUMENTS.sortDir;
} else {
	StructAppend(LOCAL.retVal,{&quot;success&quot; = false, &quot;message&quot; = &quot;Your sort criteria is not valid.&quot;},true);
	return LOCAL.retVal;
}
&lt;/code&gt;

What are we doin&apos; here? Well, we convert &lt;em&gt;sortCol&lt;/em&gt; argument to an array, and create a &lt;em&gt;LOCAL.sortCol&lt;/em&gt; variable. If our array has two items, we set our local variable to the second item. Otherwise we just use the argument. We then test the local variable for validity (is this a valid sort column?), and set our &lt;em&gt;LOCAL.orderby&lt;/em&gt;. Now we only need two minor adjustments to our javascript, to accomodate the new column. The first is in the &lt;em&gt;colModel&lt;/em&gt; in the grid config.

&lt;h4&gt;jqGridDemo.js - Grid Configuration: Column Model&lt;/h4&gt;
&lt;code&gt;
grid.jqGrid({
	...
	colModel: [
		{name: &apos;Action&apos;, index: &apos;ID&apos;, label: &apos;Action&apos;, width: 60, fixed: true, sortable: false, resizable: false, align: &apos;center&apos;, formatter: &apos;actionFormatter&apos;, key: true},
		{name: &apos;Title&apos;},
		{name: &apos;Posted&apos;, label: &apos;Release Date&apos;},
		{name: &apos;Views&apos;, align: &apos;right&apos;, width: 60, fixed: true},
		{name: &apos;categoryName&apos;}
	],
	...
});
&lt;/code&gt;

The last bit of script is to add the column in our bits that &lt;em&gt;map&lt;/em&gt; the ColdFusion return to the &lt;em&gt;colModel&lt;/em&gt;.

&lt;h4&gt;jqGridDemo.js - populateGrid: Column Mapping&lt;/h4&gt;
&lt;code&gt;
grid.jqGrid(&apos;setGridParam&apos;,{remapColumns:[
	gridCols[&apos;ID&apos;] + gridMultiSelect,
	gridCols[&apos;TITLE&apos;] + gridMultiSelect,
	gridCols[&apos;POSTED&apos;] + gridMultiSelect,
	gridCols[&apos;VIEWS&apos;] + gridMultiSelect,
	gridCols[&apos;CATEGORYNAME&apos;] + gridMultiSelect
]});
grid[0].addJSONData(d);
&lt;/code&gt;

Now we can load our template in the browser to see the result.

&lt;div style=&quot;text-align: center; margin: 0 auto;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt7.png&quot; title=&quot;jqGrid Pt 7 Grouping Demo 1&quot; /&gt;
&lt;/div&gt;

Great! We now have grouped data. We can page through, and see where new categories start. You&apos;ll notice that our total record count is much higher than before. That&apos;s because there&apos;s a one-to-many relationship between entries to categories, so entries are repeated in each category that they are a part of. This is great, but the first thing I notice is that the new column actually displays in the grid. Since the category is already the grouping header, I don&apos;t think we need to show it in the grid columns. Luckily there&apos;s an option to the &lt;em&gt;groupingView&lt;/em&gt; that will allow us to hide the column, &lt;em&gt;groupColumnShow&lt;/em&gt;.

&lt;h4&gt;jqGridDemo.js - Grid Config: groupingView&lt;/h4&gt;
&lt;code&gt;
grid.jqGrid({
	...
	grouping: true,
	groupingView: {
		groupField: [&apos;categoryName&apos;],
		groupDataSorted: true,
		groupColumnShow: false
	},
	...
});
&lt;/code&gt;

&lt;div style=&quot;text-align: center; margin: 0 auto;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt7b.png&quot; title=&quot;jqGrid Pt 7 Grouping Demo 2&quot; /&gt;
&lt;/div&gt;

This hid the column but, as you can see, it also changed the size of the grid when it removed the column. This is a bug in jqGrid, and is filed with the development team, but in the meantime you can add some code to handle this issue. Our &lt;em&gt;gridComplete&lt;/em&gt; configuration attribute is already setup to call our &lt;em&gt;gridLoadInit&lt;/em&gt; method, which is called every time the data loads. We&apos;ll add a line at the end of this method to repair our grid width.

&lt;h4&gt;jqGridDemo.js - gridLoadInit Method&lt;/h4&gt;
&lt;code&gt;
var gridLoadInit = function () {
	...
	grid.jqGrid(&apos;setGridWidth&apos;,800);
};
&lt;/code&gt;

If we reload our page again, we&apos;ll see that the grid width is now as it should be, with the column being hidden as intended. What&apos;s next?

Each grouping section header has an icon, showing the user that the sections can be collapsed or expanded. In our current configuration (the default) all sections are expanded by default. Let&apos;s change that so that they&apos;re all collapsed on load. This is easily accomplished by adding &lt;em&gt;groupCollapse&lt;/em&gt; to our &lt;em&gt;groupingView&lt;/em&gt; configuration. We&apos;ll also change the classes of the expand and collapse indicators used, so that they match up with the rest of our demo. We&apos;re using the &lt;a href=&quot;http://www.famfamfam.com/lab/icons/silk/&quot; target=&quot;_blank&quot;&gt;FamFamFam Silk&lt;/a&gt; icon library, so we&apos;ll reference some images from that.

&lt;h4&gt;jqGridDemo.js - groupingView Configuration&lt;/h4&gt;
&lt;code&gt;
groupingView: {
	groupField: [&apos;categoryName&apos;],
	groupDataSorted: true,
	groupColumnShow: false,
	groupCollapse: true,
	plusicon: &apos;bullet_toggle_plus&apos;,
	minusicon: &apos;bullet_toggle_minus&apos;
},
&lt;/code&gt;

The &lt;em&gt;plusicon&lt;/em&gt; and &lt;em&gt;minusicon&lt;/em&gt; attributes denote class references. We&apos;ll create these in our stylesheet.

&lt;h4&gt;jqGridDemo.css - icon references&lt;/h4&gt;
&lt;code&gt;
/* bullet_toggle_minus icon image for trigger */
.bullet_toggle_minus { background: url(&apos;/resources/images/icons/bullet_toggle_minus.png&apos;) no-repeat scroll 0px 0px transparent !important; }

/* bullet_toggle_plus icon image for trigger */
.bullet_toggle_plus { background: url(&apos;/resources/images/icons/bullet_toggle_plus.png&apos;) no-repeat scroll 0px 0px transparent !important; }

.ui-jqgrid tr.jqgroup td { font-size: 1.1em; font-weight: bold !important; background-color: #98AFC7; }
&lt;/code&gt;

When you reload your page you&apos;ll see that the groupings are now collapsed by default, and notice the new icons. I even added some style stuff to differentiate the headers from the data a little more clearly. Now, personally, I would prefer that all of the sections are collapsed on load, except the first one. We can do this by adding a line to our &lt;em&gt;gridLoadInit&lt;/em&gt; method.

&lt;h4&gt;jqGridDemo.js - gridLoadInit Method&lt;/h4&gt;
&lt;code&gt;
var gridLoadInit = function () {
	...
	grid.jqGrid(&apos;groupingToggle&apos;,&apos;gridTestghead_0&apos;);
	grid.jqGrid(&apos;setGridWidth&apos;,800);
};
&lt;/code&gt;

The &lt;em&gt;groupingToggle&lt;/em&gt; method is used to open or close a grouping session, taking the row id as the argument. Grouping headers are just another table row, each with it&apos;s own unique id. It&apos;s format is {grid id}ghead_{section index}. Our grid id is &lt;em&gt;gridTest&lt;/em&gt;, and JavaScript uses 0 based indexes, so the first section is index 0. Placing this in the &lt;em&gt;gridLoadInit&lt;/em&gt;, a request for data is made, the data is applied to the grid in groups, the groups are collapsed (and the column is hidden) by configuration, the load method is called, then the first section is expanded, and the width is set on the grid. Whew! That&apos;s a lot of stuff. It now looks like this.

&lt;div style=&quot;text-align: center; margin: 0 auto;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt7c.png&quot; title=&quot;jqGrid Pt 7 Grouping Demo 3&quot; /&gt;
&lt;/div&gt;

This is coming along very nicely. There&apos;s just one final thing I&apos;d like to explore here, summary rows. One common function of grouping is to have summaries of specific columns: calculations (or functions) run on each record of data in a group to arrive at some &apos;summary&apos; value. For instance, you might have some sort of user logging setup, and want to show the average number of page views per user. Or an e-commerce control panel, where you are grouping user orders, and want to show the total amount that&apos;s been spent by clients across all of their grouped orders. In our demo we show how many times each post has been viewed, so we&apos;ll break it down to the total number of views per category. We begin by adjusting our column model, to say we want to tally up the views.

&lt;h4&gt;jqGridDemo.js - jqGrid Config: Column Model&lt;/h4&gt;
&lt;code&gt;
grid.jqGrid({
	...
	colModel: [
		...
		{name: &apos;Views&apos;, align: &apos;right&apos;, width: 60, fixed: true, summaryType: &apos;sum&apos;},
		...
	],
	...
});
&lt;/code&gt;

There are several different &lt;em&gt;summaryType&lt;/em&gt;s that may be applied to a column.

&lt;ul&gt;
	&lt;li&gt;sum - apply the sum function to the current group value and return the result&lt;/li&gt;
    &lt;li&gt;count - apply the count function to the current group value and return the result&lt;/li&gt;
    &lt;li&gt;avg - apply the average function to the current group value and return the result&lt;/li&gt;
    &lt;li&gt;min - apply the min function to the current group value and return the result&lt;/li&gt;
    &lt;li&gt;max - apply the max function to the current group value and return the result&lt;/li&gt;
&lt;/ul&gt;

You can also apply a custom function, or even a template, to a column. For more information see the jqGrid wiki entry on &lt;a href=&quot;http://www.trirand.com/jqgridwiki/doku.php?id=wiki:grouping&quot; target=&quot;_blank&quot;&gt;Grouping&lt;/a&gt;. I don&apos;t have enough space in the &lt;em&gt;Views&lt;/em&gt; column to put a label on that total, so I need something in the &lt;em&gt;Release Date&lt;/em&gt; footer. Since I&apos;m not really creating a true summary of that column I need to apply an empty method to the &lt;em&gt;summaryType&lt;/em&gt;, then apply my output to the &lt;em&gt;summaryTpl&lt;/em&gt; like this:

&lt;h4&gt;jqGridDemo.js - jqGrid Config: Column Model&lt;/h4&gt;
&lt;code&gt;
var emptyMethod = function (){
	return;
};

grid.jqGrid({
	...
	colModel: [
		...
		{name: &apos;Posted&apos;, label: &apos;Release Date&apos;, summaryTpl: &apos;&lt;div class=\&quot;dateSummaryFooter\&quot;&gt;Total Views: &lt;\/div&gt;&apos;, summaryType: emptyMethod},
		...
	],
	...
});
&lt;/code&gt;

After that I adjust my &lt;em&gt;groupingView&lt;/em&gt; to give me the summary:

&lt;h4&gt;jqGridDemo.js - jqGrid Config: groupingView&lt;/h4&gt;
&lt;code&gt;
groupingView: {
	groupField: [&apos;categoryName&apos;],
	groupDataSorted: true,
	groupColumnShow: false,
	groupCollapse: true,
	plusicon: &apos;bullet_toggle_plus&apos;,
	minusicon: &apos;bullet_toggle_minus&apos;,
	groupSummary: [true]
},
&lt;/code&gt;

Then I&apos;ll add a little styling, to make it stand out, and align my &lt;em&gt;summaryTpl&lt;/em&gt; output.

&lt;h4&gt;jqGridDemo.css&lt;/h4&gt;
&lt;code&gt;
div.dateSummaryFooter { text-align: right; }

tr.jqfoot td { background-color: #736F6E; color: #FFF; }
&lt;/code&gt;

When you refresh the page you&apos;ll see how it all lays out.

&lt;div style=&quot;text-align: center; margin: 0 auto;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt7d.png&quot; title=&quot;jqGrid Pt 7 Grouping Demo 3&quot; /&gt;
&lt;/div&gt;

As you can see, grouping in jqGrid is pretty easy to do. There are more options to refine your grouping view as well. See the documentation for more. As always, I welcome your feedback. Sample code can be obtained from the &lt;b&gt;Download&lt;/b&gt; link below.
				</description>
				
				<category>ColdFusion</category>
				
				<category>JQuery</category>
				
				<category>Development</category>
				
				<category>jqGrid</category>
				
				<pubDate>Wed, 04 Apr 2012 17:02:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/4/4/Intro-to-jqGrid-Part-7-Grouping</guid>
				
				
				<enclosure url="http://www.cutterscrossing.com/enclosures/jqGridDemo-pt7.zip" length="2477723" type="application/zip"/>
				
			</item>
			
			<item>
				<title>ColdFusion Security Hotfix and Big Forms</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/3/27/ColdFusion-Security-Hotfix-and-Big-Forms</link>
				<description>
				
				The other day, Adobe released &lt;a href=&quot;http://www.adobe.com/support/security/bulletins/apsb10-18.html&quot; target=&quot;_blank&quot;&gt;a new Security Hotfix&lt;/a&gt; for it&apos;s &lt;a href=&quot;http://www.adobe.com/products/coldfusion&quot; target=&quot;_blank&quot;&gt;ColdFusion&lt;/a&gt; server. There were a number of things addressed in the hotfix, to help protect against Denial of Service attack using a hash algorithm collision. (My wife would say I sound like Charlie Brown&apos;s teacher right about now.) Ok, the important thing is you need to update your server.

Now for the fun part. We loaded the fix to our testing servers to run our app around the block prior to pushing this up to production. And, it&apos;s a good thing we did. We&apos;re preparing for a large deployment, and testing is pretty heavy right now. First thing in is that a form would no longer submit, throwing a 500 error every time. I didn&apos;t &lt;em&gt;show&lt;/em&gt; me a 500 error, just a blank page. I had to look at Firebug to see the error code response. Now, if you&apos;ve ever encountered a 500 error from the server then you know they don&apos;t typically tell you much. I reproduced the error locally and then went looking through the log files on the server.

In a multi-server configuration there are two core areas to look at log files. The first are the basic JRun logs. On a Windows systems, these files are located in the &lt;em&gt;C:\JRun4\logs&lt;/em&gt; folder. Here you will typically find a &lt;em&gt;{instance}-out.log&lt;/em&gt; file, and a &lt;em&gt;{instance}-event.log&lt;/em&gt; file, for each ColdFusion instance you have configured. Right out of the gate you have &lt;em&gt;admin-event&lt;/em&gt; and &lt;em&gt;admin-out&lt;/em&gt; logs for the JRun administrator, and &lt;em&gt;cfusion-event&lt;/em&gt; and &lt;em&gt;cfusion-out&lt;/em&gt; for the default ColdFusion instance. I checked both files for my instance, and saw there weren&apos;t any items to tell me about the 500 error, so I then went looking at the ColdFusion logs.

Each ColdFusion instance has it&apos;s own set of log files, that you can see in the logs viewer in the ColdFusion Administrator. That said, the ColdFusion Administrator is not really the best place to go through these files, especially when you&apos;re really having issues. At this point, you just want to open them yourself. First, you have to find them. You do this through your instance, &lt;em&gt;C:\JRun4\servers\{instance}\cfusion.ear\cfusion.war\WEB-INF\cfusion\logs&lt;/em&gt;. You&apos;ll probably find multiple log files here, from the &lt;em&gt;application&lt;/em&gt; and &lt;em&gt;eventgateway&lt;/em&gt; and &lt;em&gt;mail&lt;/em&gt; logs, to individual logs from &lt;em&gt;cflog&lt;/em&gt; calls.

Our issue, with submitting our form, was answered by the JRun &lt;em&gt;-event&lt;/em&gt; logs, which gave me a few error messages saying something like this:

&lt;code&gt;
03/27 07:52:00 error ROOT CAUSE: 
coldfusion.filter.FormScope$PostParametersLimitExceededException: POST parameters exceeds the maximum limit specified in the server.
	at coldfusion.filter.FormScope.parseQueryString(FormScope.java:397)
	at coldfusion.filter.FormScope.parsePostData(FormScope.java:346)
	at coldfusion.filter.FormScope.fillForm(FormScope.java:296)
	at coldfusion.filter.FusionContext.SymTab_initForRequest(FusionContext.java:377)
	at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:33)
	at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
	at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
	at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126)
	at coldfusion.CfmServlet.service(CfmServlet.java:200)
	at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
	at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
	at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
	at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
	at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
	at jrun.servlet.FilterChain.service(FilterChain.java:101)
	at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
	at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
	at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
	at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
	at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
	at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
	at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
&lt;/code&gt;

&quot;Dude! What is that!?!&quot; Well, luckily I had installed my security hotfix, locally, just that morning, so I remember reading over the instructions. In it&apos;s notes it had stated the following:

&lt;ol start=&quot;4&quot;&gt;
	&lt;li&gt;Customers who want to change postParameterLimit, go to {ColdFusion-Home}/lib for Server installation or {ColdFusion-Home}/WEB-INF/cfusion/lib for Multiserver or J2EE installation. Open file neo-runtime.xml, after line
&lt;code&gt;
&quot;&lt;var name=&apos;postSizeLimit&apos;&gt;&lt;number&gt;100.0&lt;/number&gt;&lt;/var&gt;&quot;
&lt;/code&gt;
	add the below line and you can change 100 with desired number.
&lt;code&gt;
&quot;&lt;var name=&apos;postParametersLimit&apos;&gt;&lt;number&gt;100.0&lt;/number&gt;&lt;/var&gt;&quot;
&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

Just a heads up, that &lt;em&gt;neo-runtime.xml&lt;/em&gt; file is minified, so you&apos;ll want to &lt;em&gt;&lt;u&gt;F&lt;/u&gt;ind&lt;/em&gt; &quot;postSizeLimit&quot; to get that statement in the right place. We tried that &lt;em&gt;postParametersLimit&lt;/em&gt; value (100) and found that our form had more than that (many were hidden, but that&apos;s another post all together), so we adjusted the number to 200. After restarting the instance again, we tested the form once more with complete success.

Hopefully this will help someone else avoid this issue. It&apos;s important to remember that Adobe does try to document these types of situations with hotfixes, so when you run into issues they should be your first source of troubleshooting information.
				</description>
				
				<category>Adobe</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Tue, 27 Mar 2012 14:41:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/3/27/ColdFusion-Security-Hotfix-and-Big-Forms</guid>
				
				
			</item>
			
			<item>
				<title>Intro to jqGrid Part 6: The Action Column</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/3/16/Intro-to-jqGrid-Part-6-The-Action-Column</link>
				<description>
				
				So far we&apos;ve covered &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/19/Intro-to-jqGrid&quot;&gt;the base grid configuration&lt;/a&gt;, populating the grid &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/20/Intro-to-jqGrid-Part-2-Getting-the-Data&quot;&gt;with remote data&lt;/a&gt;, controlling layout by &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/28/Intro-to-jqGrid-Part-3-Columns&quot;&gt;refining the column model&lt;/a&gt;, and given an &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/1/4/Intro-to-jqGrid-Part-4-Event-Handling&quot;&gt;example of event handling&lt;/a&gt; by binding a search form to our grid. This covers most of what the average developer might need to know about working with jqGrid, but I&apos;ve been promising to tell you how to work with the icons we setup in our action column.jqGrid provides the ability to add predefined &apos;action&apos; icons directly. That said, it&apos;s a small, predefined set of actions, and they build out dialogs and forms according to configuration details. This might be nice for prototyping, or small applications, but most of us already have interfaces for editing and stuff. I like finer control over the &apos;look&apos; of my interfaces, and prefer to use stuff that&apos;s already built, if we have it. So, we make our own &apos;action&apos; icons, and attach our own custom events.

First, let&apos;s look again at the custom cell renderer that we wrote for our &apos;action&apos; column:

&lt;code&gt;
$.extend($.fn.fmatter, {
	actionFormatter: function(cellvalue, options, rowObject) {
		var retVal = &quot;&lt;span class=\&apos;icon-trigger action-trigger pencil\&apos; rel=\&apos;&quot; + cellvalue + &quot;\&apos; \/&gt;&quot;;
		retVal += &quot;&lt;span class=\&apos;icon-trigger action-trigger delete\&apos; rel=\&apos;&quot; + cellvalue + &quot;\&apos; \/&gt;&quot;;
		return retVal;
	}
});
&lt;/code&gt;

Yeah, this one was pretty simple. All it did was add two icons to the display and apply the cell value to the &lt;em&gt;rel&lt;/em&gt; attribute. The cell value, in our case, is the ID column, which is the unique reference you would want for this type of scenario. Now, the first thing you might notice, in reviewing the current output, is that something looks a little off. Can you spot it?

&lt;div style=&quot;text-align:center;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt6.png&quot; /&gt;
&lt;/div&gt;

If you look close you can see it. Every other row the icons and text are a little washed out. This is because of the &lt;em&gt;altRows&lt;/em&gt; option we used in our jqGrid configuration. Removing that option will remove the alternate row highlighting, which is causing the washout effect. Here, let&apos;s run a little experiment. First, remove the &lt;em&gt;altRows&lt;/em&gt; attribute from our grid configuration. A quick reload will show you the washout is gone, just like I said. Now, let&apos;s create a new style declaration in our stylesheet.

&lt;code&gt;
table#gridTest tr:even td { background-color: #F5F5F5; }
&lt;/code&gt;

If you reload the page you&apos;ll notice that didn&apos;t do anything. Why is that? Well, good question. Maybe it&apos;s because the rows don&apos;t exist until after the request is made. Let&apos;s take a different tact. Let&apos;s change that style declaration, making it define a class.

&lt;code&gt;
.evenRow { background-color: #F5F5F5; }
&lt;/code&gt;

Next, let&apos;s add a line to the end of our &lt;em&gt;gridLoadInit&lt;/em&gt; method.

&lt;code&gt;
$(&apos;table#gridTest tr:even td&apos;).addClass(&apos;evenRow&apos;);
&lt;/code&gt;

Now refresh your grid. You get the grid highlighting without the washout effect. Cool! You might remember that, in a &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/1/13/Intro-to-jqGrid-Part-5-Some-Other-Stuff&quot;&gt;previous post&lt;/a&gt;, the &lt;em&gt;gridLoadInit&lt;/em&gt; method is attached to the grid&apos;s &lt;em&gt;gridComplete&lt;/em&gt; configuration option, and fires each time data is loaded into the grid. That method becomes very important, as it allows you to do things with the records/rows once they are loaded. &quot;But, what does this have to do with the &apos;Action&apos; column stuff?&quot; Well, that leads to our first method of attaching event handlers to our action icons.

&lt;h3&gt;Bound Handlers&lt;/h3&gt;

For a number of reasons, I&apos;m using an older version of &lt;a href=&quot;http://www.jquery.com&quot; target=&quot;_blank&quot;&gt;JQuery&lt;/a&gt; in these posts. You do have access to &lt;em&gt;.live()&lt;/em&gt; binding, but sometimes it&apos;s nice to really take control of when you are binding/unbinding events. Basically, we want to apply event handlers to every row after it loads, and remove those bindings before we load new records. We&apos;ll start by creating a new method that we can call from within our &lt;em&gt;gridLoadInit&lt;/em&gt; method. You could put all of the code directly in the method, but let&apos;s break it up a little to make maintenance a little easier. We&apos;ll write a new &lt;em&gt;bindActionHandlers&lt;/em&gt; method inside our &lt;em&gt;$(document).ready()&lt;/em&gt;.

&lt;code&gt;
/*
 * FUNCTION bindActionHandlers
 * This method is called within the gridLoadInit() method, and is used to
 * bind event handlers to the action icons of new records
 */
var bindActionHandlers = function () {
	
};
&lt;/code&gt;

Here we&apos;ll place all of our code to create new event bindings for our action columns. Let&apos;s start by binding a click handler to our &lt;em&gt;delete&lt;/em&gt; icons.

&lt;code&gt;
var bindActionHandlers = function () {
	// Delete icon binding
	$(&apos;span.delete[class*=&quot;action-trigger&quot;]&apos;, grid).bind(&quot;click&quot;, function(e){
		e.preventDefault();
		
		return false;
	});
};
&lt;/code&gt;

What we&apos;re saying here is a) apply this method as the click handler to &lt;em&gt;delete&lt;/em&gt; icons inside our grid that include the &lt;em&gt;action-trigger&lt;/em&gt; class, and b) prevent any default click action and return false when we&apos;re done. Now, let&apos;s think about this a minute. What would we expect a user to see and do when they are trying to delete this record? Well, we probably want to make sure that they really want to remove the record. Let&apos;s build them a little confirmation dialog. First, we probably need to know which record they&apos;re trying to remove. We probably also want to show them the title of the record in the confirmation. Let&apos;s set up some function local variables.

&lt;code&gt;
var bindActionHandlers = function () {
	// Delete icon binding
	$(&apos;span.delete[class*=&quot;action-trigger&quot;]&apos;).bind(&quot;click&quot;, function(e){
		e.preventDefault();
		var row = $(this).parent().parent(),
			rowId = row.attr(&quot;id&quot;), 
			recId = $(this).attr(&apos;rel&apos;),
			title =	grid.jqGrid(&apos;getCell&apos;,rowId,&apos;Title&apos;);
            
		return false;
	});
};
&lt;/code&gt;

OK, this gets us the &lt;em&gt;id&lt;/em&gt; of the record, along with the &lt;em&gt;title&lt;/em&gt;. Now we&apos;ll build a little confirmation box.

&lt;code&gt;
var bindActionHandlers = function () {
	// Delete icon binding
	$(&apos;span.delete[class*=&quot;action-trigger&quot;]&apos;).bind(&quot;click&quot;, function(e){
		e.preventDefault();
		var row = $(this).parent().parent(),
			rowId = row.attr(&quot;id&quot;), 
			recId = $(this).attr(&apos;rel&apos;),
			title =	grid.jqGrid(&apos;getCell&apos;,rowId,&apos;Title&apos;);
		// Create a dynamic dialog, that is destroyed when closed
		$(&apos;&lt;div&gt;&apos;).dialog({
			title:&apos;Delete Confirmation&apos;,
			width:425,
			height:200,
			modal:true,
			create: function(){
				$(&apos;span.ui-icon-closethick&apos;).html(&quot;&quot;);
			},
			close:function(){
				$(this).dialog(&apos;destroy&apos;);
			},
			buttons:[
			    {text:&apos;OK&apos;,
			    click:function(){
			    	deleteItem(rowId,recId,$(this));
			    }},
			    {text:&apos;Cancel&apos;,
			    click:function(){
			    	$(this).dialog(&apos;close&apos;);
			    }}
			]
		}).html(&quot;Are you sure you want to delete the following?:&lt;br /&gt;&quot;+title);
		return false;
	});
};
&lt;/code&gt;

Now we create a &lt;a href=&quot;http://www.jqueryui.com&quot; target=&quot;_blank&quot;&gt;JQueryUI&lt;/a&gt; dialog on the fly, to use as a confirmation box. We setup &lt;em&gt;OK&lt;/em&gt; and &lt;em&gt;Cancel&lt;/em&gt; click handlers, and dynamically set the text of the dialog to reflect the &lt;em&gt;title&lt;/em&gt; of the record being deleted. We also call a&lt;em&gt;deleteItem()&lt;/em&gt; method, to &lt;em&gt;delete&lt;/em&gt; the record. We&apos;ll build that later. Now that we&apos;ve put all of this together, all we need to do is add a call to the &lt;em&gt;bindActionHandlers()&lt;/em&gt; method to the end of our &lt;em&gt;gridLoadInit()&lt;/em&gt; method.

&lt;code&gt;
var gridLoadInit = function () {
	// if the &apos;selected&apos; array has length
	// then loop current records, and &apos;check&apos;
	// those that should be selected
	if(selArr.length &gt; 0){
		var tmp = grid.jqGrid(&apos;getDataIDs&apos;);
		$.each(selArr, function(ind, val){
			var pos = $.inArray(val, tmp);
			if(pos &gt; -1){
				grid.jqGrid(&apos;setSelection&apos;,val);
			}
		});
	}
	
	$(&apos;table#gridTest tr:even td&apos;).addClass(&apos;evenRow&apos;);
	bindActionHandlers();
};
&lt;/code&gt;

Now let&apos;s reload the page, and click the &lt;em&gt;delete&lt;/em&gt; icon of our first row.

&lt;div style=&quot;text-align:center;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt6b.png&quot; /&gt;
&lt;/div&gt;

The downside to dynamically applying your event handlers like this is that you also need to &lt;em&gt;unbind&lt;/em&gt; handlers before you refresh your data. We already stubbed out a method for this in our &lt;em&gt;$(document).ready()&lt;/em&gt;, &lt;em&gt;gridUnloader&lt;/em&gt;.

&lt;code&gt;
/*
 * FUNCTION gridUnloader
 * Called from within the populateGrid method, this method is to unbind
 * any event handlers created during grid load, by the gridLoadInit method.
 */
var gridUnloader = function () {
	
};
&lt;/code&gt;

After that you just add the code to &lt;em&gt;unbind&lt;/em&gt; the click handler

&lt;code&gt;
var gridUnloader = function () {
	$(&apos;span.delete:not(&quot;disabled-trigger&quot;)&apos;, grid).unbind(&apos;click&apos;);
};
&lt;/code&gt;

This says &lt;em&gt;unbind&lt;/em&gt; any &lt;em&gt;click&lt;/em&gt; handler applied to a grid&apos;s &lt;em&gt;delete&lt;/em&gt; icons that don&apos;t have a class of &lt;em&gt;disabled-trigger&lt;/em&gt;. (&quot;Hey Cutter! What&apos;s That!&quot; All in good time...) Now that you have the method, all you have to do is call it from the correct point of context. Within the &lt;em&gt;data&lt;/em&gt; grid config option, which handles all requests for grid data, we had a piece of code that runs on the first request (to map column positions). This is in a conditional that basically says &quot;if not set, then set it&quot;. We put an &lt;em&gt;else&lt;/em&gt; clause here, to now see &quot;if it is set, then we&apos;re reloading the grid. We know if we&apos;re reloading we need to &lt;em&gt;unbind&lt;/em&gt; all our row level event handlers, so this is where our call to &lt;em&gt;gridUnloader&lt;/em&gt; will go.

&lt;code&gt;
var populateGrid = function (postdata) {
	$.ajax({
		url: &apos;/com/cc/Blog/Entries.cfc&apos;,
		data: $.extend(true, {}, postdata, {search: $.toJSON(scrubSearch())}),
		method:&apos;POST&apos;,
		dataType:&quot;json&quot;,
		success: function(d,r,o){
			if(d.success){
				
				// If loading for the first time, let&apos;s find out to which
				// array positions our columns map.
				if(!gridCols.set){
					columnSetup(d.data);
				} else {
					// Unbind any bound event handlers in the current grid data
					// Only necessary after the first grid load
					gridUnloader();
				}

				grid.jqGrid(&apos;setGridParam&apos;,{remapColumns:[
					gridCols[&apos;ID&apos;] + gridMultiSelect,
					gridCols[&apos;TITLE&apos;] + gridMultiSelect,
					gridCols[&apos;POSTED&apos;] + gridMultiSelect,
					gridCols[&apos;VIEWS&apos;] + gridMultiSelect
				]});
				grid[0].addJSONData(d);
			} else {
				console.log(d.message);
			}
		}
	});
};
&lt;/code&gt;

Let&apos;s stop and take a minute to build that &lt;em&gt;deleteItem&lt;/em&gt; method, and the remote method it will call. There&apos;s a few things that need to happen.

&lt;ol&gt;
	&lt;li&gt;Make an ajax call to remove the record&lt;/li&gt;
    &lt;li&gt;If the call is successful, remove the row from the grid&lt;/li&gt;
    &lt;li&gt;If the call fails, show a message to the user&lt;/li&gt;
    &lt;li&gt;Close the Delete Confirmation dialog box&lt;/li&gt;
&lt;/ol&gt;

Let&apos;s start by writing a quick dialog configuration object for our generic error dialog. We&apos;ll place this inside our &lt;em&gt;$(document).ready()&lt;/em&gt; statement.

&lt;code&gt;
// Error dialog box config
$(&apos;div#grid-dialog-error&apos;).dialog({
	width:400,
	autoOpen: false,
	modal: true,
	create: function(){
		$(&apos;span.ui-icon-closethick&apos;).html(&quot;&quot;);
	},
	buttons:{
		&quot;OK&quot;: function(){
			$(this).dialog(&quot;close&quot;);
		}
	}
});
&lt;/code&gt;

We&apos;ll use this in a few places going forward. Right now, let&apos;s write our ajax call for removing a blog entry.

&lt;code&gt;
/*
 * FUNCTION deleteItem
 * This method is for deleting records and removing the
 * corresponding grid entry
 * @rowId (int) - ID of the row to be removed from the grid
 * @recId (string) - The UUID of the blog entry to be removed
 * @dlg (object) - JQuery element of the JQUI dialog
 */
var deleteItem = function (rowId, recId, dlg) {
	$.ajax({
		url: &apos;/com/cc/Blog/Entries.cfc&apos;,
		data: {
			method: &apos;deleteEntry&apos;,
			recId:recId,
			returnFormat: &apos;json&apos;
		},
		dataType: &apos;json&apos;,
		success: function(d, r, o){
			if (d.success) {
				grid.jqGrid(&apos;delRowData&apos;,rowId);
				dlg.dialog(&apos;close&apos;);
			}
			else {
				$(&apos;span#grid-dialog-error-message&apos;).html(d.message);
				$(&apos;div#grid-dialog-error&apos;).dialog(&apos;open&apos;);
			}
		}
	});
};
&lt;/code&gt;

This will make an ajax call to remove the record. If the call is successful, then the row will be removed and the dialog closed. If it fails, then our new error dialog will open to tell us why. This tells us a little about how we need to form our remote method.

&lt;code&gt;
/**
 *	FUNCTION deleteEntry
 *	Used to remove entries from the system
 *
 *	@access remote
 *	@returnType struct
 *	@output false
 */
function deleteEntry(required string recId){
	LOCAL.retVal = {&quot;success&quot; = true, &quot;message&quot; = &quot;&quot;, &quot;data&quot; = &quot;&quot;};

	// BEST PRACTICE: You&apos;ll want to verify that the user has the right to do this. Normally, that would go here.

	LOCAL.sql = &quot;DELETE FROM tblblogentries
				 WHERE id = :recId&quot;;
	LOCAL.q = new Query(sql = LOCAL.sql);
	LOCAL.q.addParam(name = &quot;recId&quot;, value = ARGUMENTS.recId, cfsqltype = &quot;cf_sql_varchar&quot;);
	try {
		// You would uncomment the following line to actually remove records, and remove the throw statement
		// LOCAL.q.execute();
		throw (message = &quot;Intentional Exception: You didn&apos;t really think I&apos;d delete entries, did you?&quot;, type = &quot;custom_err&quot;, errorCode = &quot;ce1001&quot;);
	} catch (any excpt) {
		// In testing, and with the .execute() commented out above, comment out the next line to watch the grid remove a row
		LOCAL.retVal.success = false;
		LOCAL.retVal.message = excpt.message;
	}
	return LOCAL.retVal;
}
&lt;/code&gt;

Yes, I didn&apos;t really delete anything. The code is there, but we&apos;re not killing entries today. This does give you the basic idea on how this all works though. Trying to delete an item in the grid now will show you a confirmation dialog. When you click on &lt;em&gt;OK&lt;/em&gt; the ajax call is made. Right now, we intentionally throw an error. The success marker causes the error dialog to display with the message. If you comment out the first line of the &lt;em&gt;catch&lt;/em&gt;, in this method, and re-run your test, you will see the confirmation dialog close, and the deleted record&apos;s row removed from the grid.

&lt;h3&gt;Old School Event Handler&lt;/h3&gt;

Nowadays, it&apos;s standard practice to &lt;em&gt;bind&lt;/em&gt; event handlers at runtime. It&apos;s even referred to as best practice. That said, there are issues with these new methods, particularly in making sure to &lt;em&gt;unbind&lt;/em&gt; events from items you&apos;re removing from the DOM (or when they aren&apos;t needed at all). Binding events at runtime has runtime implications, and can cause memory leaks if not carefully controlled. For this reason, sometimes it just makes more sense to take it on the old school way. To demonstrate, let&apos;s take a different tact with how we handle our &lt;em&gt;edit&lt;/em&gt; icons.

&lt;code&gt;
$.extend($.fn.fmatter, {
	actionFormatter: function(cellvalue, options, rowObject) {
		var retVal = &quot;&lt;a href=\&apos;javascript:void(0)\&apos; onclick=\&apos;editEntry(\&quot;&quot; + cellvalue + &quot;\&quot;)\&apos;&gt;&lt;span class=\&apos;icon-trigger action-trigger pencil\&apos; rel=\&apos;&quot; + cellvalue + &quot;\&apos; \/&gt;&lt;/a&gt;&quot;;
		retVal += &quot;&lt;span class=\&apos;icon-trigger action-trigger delete\&apos; rel=\&apos;&quot; + cellvalue + &quot;\&apos; \/&gt;&quot;;
		return retVal;
	}
});
&lt;/code&gt;

We put a standard anchor tag in there, with the &lt;em&gt;onclick&lt;/em&gt; attribute calling a new method, &lt;em&gt;editEntry&lt;/em&gt;, to which we pass the Entry ID (cellvalue). It&apos;s not elegant, but it works. To prove that, let&apos;s build out our &lt;em&gt;editEntry&lt;/em&gt; method. We don&apos;t want to build a full Blog entry editor in this blog post, but we can create a quick page to load in a dialog via an ajax call.

&lt;code&gt;
&lt;cfsetting enablecfoutputonly=&quot;true&quot; /&gt;

&lt;cfparam type=&quot;string&quot; name=&quot;FORM.recId&quot; default=&quot;&quot; /&gt;

&lt;cfif !Len(FORM.recId)&gt;
	&lt;cfoutput&gt;You must supply an ID of a record to edit!&lt;/cfoutput&gt;
	&lt;cfabort /&gt;
&lt;/cfif&gt;

&lt;cfoutput&gt;
	&lt;p style=&quot;font-weight:bold;&quot;&gt;You are editing #FORM.recId#
&lt;/cfoutput&gt;

&lt;cfsetting enablecfoutputonly=&quot;false&quot; /&gt;
&lt;/code&gt;

This is just a simple template that takes a single POST variable (recId) and outputs it on the page. Now all you need is the ajax call to render this in a dialog box.

&lt;code&gt;
var editEntry = function (recId) {
	$(&apos;&lt;div id=&quot;recordEdit&quot;&gt;&apos;).dialog({
		title: &apos;Entry Editor&apos;,
		modal:true,
		width: $(window).width()*.6,
		height: $(window).height()*.6,
		create: function(){
			$(&apos;span.ui-icon-closethick&apos;).html(&quot;&quot;);
		},
		open: function(){
			var dlg = $(this);
			// Get the summary for the selected lesson
			$.ajax({
				url: &apos;/edit.cfm&apos;,
				type: &apos;POST&apos;,
				data:{
					recId: recId
				},
				dataType:&apos;script&apos;,
				success: function(d, r, o){
					dlg.html(d);
				}
			});
		},
		close:function(){
			$(this).html(&apos;&apos;).dialog(&apos;destroy&apos;);
			setTimeout(&apos;$(&quot;#recordEdit&quot;).remove();&apos;,100);
		},
		buttons:[{
			text:&apos;Close&apos;,
			click:function(){
				$(this).dialog(&apos;close&apos;);
			}
		}]
	});
};
&lt;/code&gt;

Here we create a div element on the fly. Pay special attention to our &lt;em&gt;close&lt;/em&gt; config option, where we have to pull off some trickery to &lt;em&gt;destroy&lt;/em&gt; the JQueryUI Dialog, and &lt;em&gt;remove&lt;/em&gt; the div from the DOM. This is very important, because every time we click on an &lt;em&gt;edit&lt;/em&gt; icon it is going to create and open a new dialog. In the &lt;em&gt;open&lt;/em&gt; config option we make an ajax call to retrieve &lt;em&gt;edit.cfm&lt;/em&gt;, passing it the record ID (recId) of the record we want to edit. We place the return of the request in the content of the JQueryUI Dialog, which we sized to take up 60% of the window size.

&lt;h3&gt;Wrap It Up&lt;/h3&gt;

At this point I think we have a pretty good &quot;Intro&quot; to jqGrid. If there&apos;s some critical piece of info you think I have missed, please feel free to let me know through the &lt;b&gt;Contact&lt;/b&gt; link below. Sample code for our application can be found below, from the &lt;b&gt;Download&lt;/b&gt; link. As always, give me your feedback and questions.
				</description>
				
				<category>Ajax</category>
				
				<category>ColdFusion</category>
				
				<category>JQuery</category>
				
				<category>Development</category>
				
				<category>jqGrid</category>
				
				<pubDate>Fri, 16 Mar 2012 10:19:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/3/16/Intro-to-jqGrid-Part-6-The-Action-Column</guid>
				
				
				<enclosure url="http://www.cutterscrossing.com/enclosures/jqGridDemo-pt6.zip" length="4627095" type="application/zip"/>
				
			</item>
			
			<item>
				<title>ColdFusion JSON Serialization Changes</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/2/28/ColdFusion-JSON-Serialization-Changes</link>
				<description>
				
				Because I&apos;ve had to search on this three times in the last year, I thought it&apos;d be a good idea to document this here, for myself and others. There were a number of important changes that can trip you up from version to version and, if you know which version the changes came in it can be beneficial.

First is a change that affects JSON output, though it&apos;s not specifically about JSON. The &lt;a href=&quot;http://www.adobe.com/support/coldfusion/downloads_updates.html&quot; target=&quot;_blank&quot;&gt;ColdFusion 9.01&lt;/a&gt; updater (the current base install, at the time of this post) addressed Bug 82980 by removing ColdFusion Debug Output from direct CFC requests. This was only important if you had debugging output turned on in the Administrator, but caused lots of issues when testing ajax applications in development environments that kept that setting on by default.

Unfortunately, Adobe made some changes to JSON serialization that were not only unpopular, but technically dead wrong. They were trying to resolve the treatment of numbers in JSON serialization. Numbers were being converted to floats (1 became 1.0, 12 became 12.0, and so forth), so Adobe changed that by converting all numbers into strings (11 became &quot;11&quot;, 17.24 became &quot;17.24&quot;). This was wrong too, as numbers weren&apos;t numeric anymore. At the time it &lt;a href=&quot;http://www.raymondcamden.com/index.cfm/2010/7/21/Not-happy-with-the-CF901-JSON-Changes&quot; target=&quot;_blank&quot;&gt;raised quite a stir&lt;/a&gt;.

They fixed this (Bug 83638) really quickly, releasing&lt;a href=&quot;http://kb2.adobe.com/cps/862/cpsid_86263.html&quot; target=&quot;_blank&quot;&gt;Cumulative Hotfix 1 for ColdFusion 9.01&lt;/a&gt;, which fixed the issue of integers being converted to float and having them as numeric values (ie: [1,12,true,&quot;this var&quot;,17.24]). Hurray! Except....

Enter the improperly titled &lt;a href=&quot;http://kb2.adobe.com/cps/918/cpsid_91836.html&quot; target=&quot;_blank&quot;&gt;Cumulative Hotfix 2 for ColdFusion 9.01&lt;/a&gt;. I say this because it really isn&apos;t &apos;cumulative&apos;. Most things are straight, from a cumulative standpoint, with the seeming exception of the fix to JSON formatting. If you have not applied CHF 1 prior to installing CHF 2, then you will still have issues with JSON formatting.

Overall, Hotfix 2 is great, fixing many bugs. The install is crazy/scary, and must be followed to the letter to prevent major issues, but it&apos;s worth it. As long as you did apply CHF 1 first, that is. Thankfully the hotfix/upgrade install process is much better in ColdFusion 10.

Big thanks to &lt;a href=&quot;http://www.raymondcamden.com&quot; target=&quot;_blank&quot;&gt;Ray&lt;/a&gt; for helping me to realize that I wasn&apos;t crazy, and pointing me in the right directions for all of this info. Hopefully this helps someone down the line.
				</description>
				
				<category>Adobe</category>
				
				<category>Ajax</category>
				
				<category>ColdFusion</category>
				
				<category>JSON</category>
				
				<category>Development</category>
				
				<pubDate>Tue, 28 Feb 2012 13:23:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/2/28/ColdFusion-JSON-Serialization-Changes</guid>
				
				
			</item>
			
			<item>
				<title>ColdFusion 10 Public Beta</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/2/21/ColdFusion-10-Public-Beta</link>
				<description>
				
				Yes, everyone is talking about it. That&apos;s why I waited a day or two to post the info. Adobe has put &lt;a href=&quot;http://labs.adobe.com/technologies/coldfusion10/&quot; target=&quot;_blank&quot;&gt;ColdFusion 10&lt;/a&gt; up on Adobe Labs, opening it&apos;s public beta cycle prior to full release. That&apos;s right folks, ColdFusion is finally hitting the double digits, and this release just continues to improve this great platform.

There are some big changes. First are some overdue upgrades, like retiring the JRun JEE server, replacing it with &lt;a href=&quot;http://tomcat.apache.org/&quot; target=&quot;_blank&quot;&gt;Tomcat&lt;/a&gt;. Web Services support is upgraded, moving to more current form of Axis, and adding native support for creating RESTful web services. Exchange integration support is now upgraded to support MS Exchange 2010. Java and Solr integrations are improved as well. Finally, we get hotfix notifications and one touch upgrade directly within the administrator. I&apos;m just getting started.

ColdFusion has always been known for making the hard things easy, and it looks like ColdFusion 10 is no exception. Adobe&apos;s engineering team listened to customer feedback, giving us a &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSd160b5fdf5100e8f639b4550129d6ce3d4f-8000.html&quot; target=&quot;_blank&quot;&gt;lot of new toys to play with&lt;/a&gt;, including some great &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSf23b27ebc7b554b664dd90601357fb06a77-7ffd.html&quot; target=&quot;_blank&quot;&gt;language enhancements&lt;/a&gt;. Highlights include important new array functions, app specific in-memory file system, MIME type checking on file uploads, an implicit CFC constructor, method chaining, and much, much more.

Oh, and closures. Did I mention closures? Not sure how this one will play out, yet, but I look forward to seeing what people come up with. There&apos;s also websockets, media player changes, and an entirely new charting to work with. Just scratching the surface here.

Yes, there is a lot of new stuff. And, to top it all off, Adobe placed ColdFusion Builder 2.01 in Beta at the same time. There are a lot of bug fixes in here, along with the CF 10 support and more. Did I mention both the server, and the IDE, have some HTML 5 goodness baked in as well? No? You&apos;ll just have to download them and start playing. This&apos;ll be fun.
				</description>
				
				<category>Adobe</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Tue, 21 Feb 2012 16:14:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/2/21/ColdFusion-10-Public-Beta</guid>
				
				
			</item>
			
			<item>
				<title>MSOC Part 9: Application Event Handlers, The Rest</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/2/13/MSOC-Part-9-Application-Event-Handlers-The-Rest</link>
				<description>
				
				So far we&apos;ve spent a lot of time going over the different Application Event Handlers that relate to specific scope events (application, session, and request). Some ask &quot;How does this relate to MSOC?&quot;, to which I have to say &quot;Because it&apos;s important to understand application flow and control.&quot; We&apos;ll be diving into the MSOC specific bits much more in the coming posts. For now, let&apos;s wrap this part of our MSOC talk with a brief discussion of our two final Application Event Handlers: &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d2a.html&quot; target=&quot;_blank&quot;&gt;onMissingTemplate&lt;/a&gt; and &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d4a.html&quot; target=&quot;_blank&quot;&gt;onError&lt;/a&gt;.

The onMissingTemplate handler kind of does what it says. &lt;b&gt;ALERT: Pay Attention To This Next Statement.&lt;/b&gt; This handler will be automatically invoked when a &lt;em&gt;ColdFusion template or component&lt;/em&gt; is called but does not exist. Did you catch that? Yes, this only catches requests for templates/files that might be served by the ColdFusion application server. Setup a special mapping for CF to process .inc files? Yes, if the file doesn&apos;t exist, then this handler should catch that. A .html page was requested? Unless the server is mapped for CF to handle those requests, then no, your onMissingTemplate method will &lt;b&gt;not&lt;/b&gt; catch that error. You get the picture yet?

The basic layout of the onMissingTemplate method is like this:

&lt;code&gt;
/**
 *    FUNCTION onMissingTemplate
 *    Runs when a (CF) template is called that does not exist
 *    @access public
 *    @returnType boolean
 *    @output false
 */
function onMissingTemplate(required string targetpage) {
	// something goes here
	return true;
}
&lt;/code&gt;

As you can see, this method is automatically passed one argument, the page being requested. Here&apos;s another catch for you, this will only catch requests for ColdFusion processed files &lt;em&gt;in the same directory&lt;/em&gt; as your Application.cfc. So a request for mysite.com/nothere.cfm will be caught, but a request for mysite.com/some/random/path/to/nothere.cfm will not (This surprised me too, and I had to test it over and over again to make sure I wasn&apos;t missing something). Weird, huh? Well, that&apos;s ok. To be honest, the onMissingTemplate handler is better served by those who don&apos;t have access to change their own webserver. The better option is to setup a 404 handler in their web server configuration. In the &lt;a href=&quot;http://httpd.apache.org/&quot; target=&quot;_blank&quot;&gt;Apache Web Server&lt;/a&gt; you can look for the &lt;em&gt;ErrorDocument&lt;/em&gt; line, in your &lt;em&gt;httpd.conf&lt;/em&gt; file, and set it to a specific template that you setup for error handling.

&lt;code&gt;
ErrorDocument 404 /errors/404.cfm
&lt;/code&gt;

Speaking of error handling... You do do error handling, right? You wouldn&apos;t just show end users hard errors, would you? Of course not. You&apos;ve got try/catch, throw and rethrow all over the place, right?

I&apos;ve never seen an app that was made to handle every possible scenario for what a user could do. Nope, never. And, I&apos;ve never seen (or written) a perfect app. It&apos;s a mythical creature, like the unicorn, or honest politicians.Fortunately, Coldfusion gives us multiple levels of error handling capability, from the block level of try/catch to the server level error handler applied through the CF Administrator. The onError method allows us to apply an application level error handler, that catches anything not previously coded for (through try/catch). It can display (if desired) any error thrown from onApplicationStart through onRequestEnd, including errors thrown through the process of the request itself, but can not display content for errors thrown in the onSessionEnd or onApplicationEnd.

The onError event handler is formed like this:

&lt;code&gt;
/**
 *    FUNCTION onError
 *    This is an application wide error handler. Best practice would be to
 *    write process specific error handling, but this method will help
 *    you trap unexpected errors for custom notification and process
 *    @access public
 *    @returnType void
 *    @output true
 */
function onError(required  exception, required string eventname) {
	if(StructKeyExists(APPLICATION.cfc, &quot;errorHandler&quot;)){
		// If the error is thrown in onApplicationEnd or onSessionEnd, the error processor
		// will still run, but nothing will be displayed to the user
		WriteOutput(APPLICATION.cfc.errorHandler.process(argumentCollection: ARGUMENTS));
	} else {
		WriteDump(var = ARGUMENTS.exception, abort = true);
	}
}
&lt;/code&gt;

The onError method is automatically passed to argments, &lt;em&gt;exception&lt;/em&gt; (think &lt;em&gt;CFCATCH&lt;/em&gt;) and &lt;em&gt;eventname&lt;/em&gt; (the application event that the error was thrown in). In my example, I&apos;ve used an application wide error handler to process the error, and displayed it&apos;s output (if not thrown from onSessionEnd or onApplicationEnd). My handler could do any number of things, from logging to emailing the site admin to generating error code specific text response for output, to all of the above and more.

OK, that&apos;s it for the Application Event Handlers. Let&apos;s be honest, I really only glossed over them and they still took up a lot of posts. That said, it&apos;s time to get back to the core MSOC talk, even as important as understanding all of this might have been. We have things to talk about, like directory structures, shared and specific asset handling, extended application models, and more. Give me your feedback: What are your most pressing questions on running Many Sites with One Codebase?
				</description>
				
				<category>Application Setup</category>
				
				<category>MSOC</category>
				
				<category>ColdFusion</category>
				
				<category>Development</category>
				
				<pubDate>Mon, 13 Feb 2012 10:33:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/2/13/MSOC-Part-9-Application-Event-Handlers-The-Rest</guid>
				
				
			</item>
			
			<item>
				<title>The Joys of Developing for Internet Explorer</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/2/9/The-Joys-of-Developing-for-Internet-Explorer</link>
				<description>
				
				&lt;em&gt;Note: Follow the madness here to it&apos;s conclusion, to discover yet another &quot;Really? I didn&apos;t know that...&quot; IE moment, that may save you heartache and pain.&lt;/em&gt;

Is the sarcasm evident in my title? It should be. While Internet Explorer may have been &quot;groundbreaking&quot; when it was released, it has ever been the bain of the web developer&apos;s existance. Why, you ask? Because it refuses to adhere to standards, and just operates differently than everyone else. To be fair, Internet Explorer 10 is in the works, and supposedly closes the gap a fair amount (and even wins out in some of the html 5/css 3 support), and 7, 8 and 9 did progressively improve (if slowly). Unfortunately the fact remains that some companies/organizations/governments are stuck on Internet Explorer 6, or maybe even 7. If you are a web developer, and write cross-browser web applications, chances are Internet Explorer has hit you more than once in your career.

It&apos;s the dumbest things that hit you too. The most obscure &quot;WTF!?!&quot; moments that drive you crazy. That is a daily experience for me now.I&apos;ve been a server-side developer for over two decades now, but in the last several years I have dealt more and more with client-side development. Why? Well, I started with HTML, and got into Javascript when it was introduced, and then got into server-side programming, so I already had some roots. With all of the work that I&apos;ve done, working with &lt;a href=&quot;http://www.sencha.com/products/extjs/&quot; target=&quot;_blank&quot;&gt;Ext JS&lt;/a&gt; and &lt;a href=&quot;http://www.jqueryui.com&quot; target=&quot;_blank&quot;&gt;JQueryUI&lt;/a&gt;, my current position threw me to the wolves to work on standardizing our application&apos;s interface development. Fun, right? It is (a lot), but the client is one of those mixed environments that is entrenched in IE, typically at 7 or 8. They can&apos;t upgrade, so it&apos;s our responsibility to make sure that our interfaces can render and function properly in these older, buggy, non-compliant POS browsers. (Note the frustration here.) Let me layout one of those typical, what-the-hell-is-goin-on-here, Internet Explorer moments for you.

&lt;h3&gt;The Application&lt;/h3&gt;

Like most good development companies, we&apos;ve made the shift to more modular, reusable code. It&apos;s a legacy codebase, serving the client well for years, and goes through constant review, revision, update and improvement. Many of us (developers in general) would love to just scrap our current codebase and start from scratch, but that&apos;s not really practical in most situations. What happens is you begin to slowly move away from &lt;a href=&quot;http://www.laputan.org/mud/&quot; target=&quot;_blank&quot;&gt;The Big Ball of Mud&lt;/a&gt; design pattern, by replacing small pieces of your application as updates/changes are required, with more modern code. Rather than one huge application, what you end up with are small, mini-applications, that can be plugged in anywhere within an application. Each of these &apos;applications&apos; then have their own supporting files: html, javascript, and css. Welcome to the fun.

&lt;h3&gt;Collision Control&lt;/h3&gt;

At this point, the issue isn&apos;t necessarily browser specific, but rather logistics. When you start adding in multiple mini-applications, things can (and will) butt heads. You will have issues with race conditions, as multiple scripts use variables of the same names, have functions with the same name that override each other due to execution order, id&apos;s repeated in a page (IE hates this a lot), and multiple event handlers accidentally added to the same DOM controls because selectors aren&apos;t specific enough. You tighten up your DOM selectors, come up with some variable and DOM naming standards, and learn about namespacing. Each a slow, progressive step towards sanity.

Then there&apos;s the issue of accidentally loading the same files multiple times. Our application uses JQueryUI, &lt;a href=&quot;http://cfuniform.riaforge.org/&quot; target=&quot;_blank&quot;&gt;cfUniform&lt;/a&gt;, &lt;a href=&quot;http://www.tinymce.com&quot; target=&quot;_blank&quot;&gt;TinyMCE&lt;/a&gt;, and &lt;a href=&quot;http://www.trirand.com/blog/&quot; target=&quot;_blank&quot;&gt;jqGrid&lt;/a&gt; extensively. Each of these mini-apps loads it&apos;s own support files. Suddenly, you&apos;re faced with coming up with systems of control, to ensure that you aren&apos;t loading scripts and CSS multiple times.

&lt;h3&gt;Back to the Browser&lt;/h3&gt;

There&apos;s a ton of debate out there about loading multiple scripts and css files. Loading multiple files has performance issues for initial download, but maintenance is far easier with these bit modularized like your display and model. In many applications things aren&apos;t complex enough for multiple files to truly be an issue. But, when you are writing a complex application, like scheduling software, customer resource management, content management, etc., the number of &apos;modules&apos; you might include in a page can grow and grow and grow, especially if your interface makes heavy use of ajax. This is where Internet Explorer can actually force your hand into creating a better experience, unintentionally and generally when it&apos;s inconvenient.

What happens when you load up your app, and notice that your forms (cfUniform) don&apos;t appear to be styled, and your highly configured and customized &lt;abbr title=&quot;What You See Is What You Get&quot;&gt;WYSIWYG&lt;/abbr&gt; editor (TinyMCE) appears to be half loaded? But, only in IE? Well, you start troubleshooting. Maybe cfUniform didn&apos;t load? No, the stylesheet is what&apos;s important here, and Developer Tools say it&apos;s there. The editor? Did it initialize? Well, the style and font dropdown info is there, even if they aren&apos;t in dropdowns. What&apos;s going on?

You start removing script files, one at a time, to make sure there isn&apos;t a conflict. But wait, it works in everything but IE? Well, you try it anyway. You step debug things, trying to see a break. And you Google (and Google, and Google). These are my days. And, after three days of this single issue, you finally stumble on &lt;a href=&quot;http://john.albin.net/css/ie-stylesheets-not-loading&quot; target=&quot;_blank&quot;&gt;an obscure post&lt;/a&gt; (page 15 of a Google search). Please, tell me you&apos;re kidding me...

Yes, Internet Explorer (at least 6 through 9) only apply up to 31 stylesheets and/or style blocks. So, when your page (1 specific stylesheet) uses JQueryUI (1 plugin stylesheet), and a menu (3 plugin stylesheets), and a nav widget (1 plugin stylesheet), plus cfUniform (3 plugin + 2 override stylesheets), and jqGrid (1 plugin stylesheet), and TinyMCE (multiple dynamically loaded stylesheets, depending on plugin configuration), and...

You get the picture. Oh, and did I mention that some of those stylesheets were 10 line, IE only stylesheets to hack IE&apos;s different handling of CSS? Yeah, salt in the wound. To test this, I went looking for something that might be loaded by default, but wasn&apos;t needed on this page of my app (or at least, not for what I was testing). I found a few stylesheets I could disable in local development, and reloaded my page. Imagine my surprise when everything rendered as it should. I had to toggle it back and forth a few times just to verify. I think I spewed profanity for several minutes.

&lt;h3&gt;What To Do?&lt;/h3&gt;

OK, so we had already been looking to form a strategy for combining files and minification. Notice I said &quot;looking to&quot;. That is to say, we wanted one, and knew we needed one, and even done a little research, but we hadn&apos;t &lt;b&gt;solidified&lt;/b&gt; one. If we had, we&apos;d already have been working on it. Now, under the gun, with deadlines looming, we have to put it in gear. What to do? Well, in this case, improvise. Time not being on our side, we have to do this manually. Identify multiple CSS files that are used either constantly (every single page load) or extensively (85%+ page view). Combine and compress, and remove single &lt;em&gt;link&lt;/em&gt; references from the code. Now, I didn&apos;t do this completely manually. I did write a script where I could define which files, in what order, and have the script build the file, while correcting internal url references so that image paths wouldn&apos;t break. Then I used an online compressor to minify the file. After all of this work (took the good part of an afternoon), I reload my pages and all of them function as intended, in all browsers. And, compressing 10 files down to 1, I now get my form styling, and my editor displays correctly, etc.

OK, is this the ideal solution? No, we&apos;ll still develop a comprehensive (and automated) strategy. But, this gets us over the deadline hump, and proves that the multiple stylesheets were the issue, and that this type of action can correct the issue. Proof of concept. You have to start somewhere I guess. But, how much easier web development would be if we didn&apos;t have to support Microsoft&apos;s mistakes.
				</description>
				
				<category>Ajax</category>
				
				<category>ExtJS</category>
				
				<category>Sencha</category>
				
				<category>JQuery</category>
				
				<category>Usability</category>
				
				<category>Development</category>
				
				<category>jqGrid</category>
				
				<pubDate>Thu, 09 Feb 2012 10:51:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/2/9/The-Joys-of-Developing-for-Internet-Explorer</guid>
				
				
			</item>
			
			<item>
				<title>Intro to jqGrid Part 5: Search</title>
				<link>http://www.cutterscrossing.com/index.cfm/2012/1/13/Intro-to-jqGrid-Part-5-Some-Other-Stuff</link>
				<description>
				
				At this point we&apos;ve &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/19/Intro-to-jqGrid&quot;&gt;created a basic grid&lt;/a&gt;, &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/20/Intro-to-jqGrid-Part-2-Getting-the-Data&quot;&gt;filled it with data&lt;/a&gt;, &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/12/28/Intro-to-jqGrid-Part-3-Columns&quot;&gt;refined the display of our columns&lt;/a&gt; and &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2012/1/4/Intro-to-jqGrid-Part-4-Event-Handling&quot;&gt;added event handlers&lt;/a&gt; to handle multiselect options. We&apos;ve &lt;a href=&quot;http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter&quot; target=&quot;_blank&quot;&gt;used custom cell formatters&lt;/a&gt;, used a custom &lt;a href=&quot;http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#function&quot; target=&quot;_blank&quot;&gt;datatype &lt;em&gt;function&lt;/em&gt;&lt;/a&gt;, and even added and populated a &lt;a href=&quot;www.trirand.com/jqgridwiki/doku.php?id=wiki:options&quot; target=&quot;_blank&quot;&gt;toolbar&lt;/a&gt; in the process. Now let&apos;s start looking at some things that aren&apos;t necessarily jqGrid specific, but incorporate them for use in our grid. How about a search?

jqGrid includes some things for doing data search, that will automatically build modal windows and stuff. But sometimes you want to format things your own way, or incorporate jqGrid for use within an existing interface. One of the advantages for us, using the datatype &lt;em&gt;function&lt;/em&gt;, is that we can preprocess our &lt;em&gt;postdata&lt;/em&gt; prior to the ajax request.First, let&apos;s add a simple form to our example:

&lt;h4&gt;index.html - Simple Search&lt;/h4&gt;

&lt;code&gt;
&lt;form action=&quot;&quot; name=&quot;searchForm&quot; id=&quot;searchForm&quot;&gt;
	&lt;fieldset title=&quot;Search&quot;&gt;
		&lt;label for=&quot;title&quot;&gt;Title&lt;/label&gt;&lt;br /&gt;
		&lt;input type=&quot;text&quot; name=&quot;title&quot; size=&quot;100&quot; /&gt;&lt;br /&gt;
		&lt;div class=&quot;col&quot;&gt;
			&lt;label for=&quot;from&quot;&gt;From&lt;/label&gt;&lt;br /&gt;
			&lt;input type=&quot;text&quot; name=&quot;from&quot; class=&quot;addDatePicker&quot; /&gt;
		&lt;/div&gt;
		&lt;div class=&quot;col&quot;&gt;
			&lt;label for=&quot;to&quot;&gt;To&lt;/label&gt;&lt;br /&gt;
			&lt;input type=&quot;text&quot; name=&quot;to&quot; class=&quot;addDatePicker&quot; /&gt;
		&lt;/div&gt;&lt;br clear=&quot;all&quot; /&gt;
        To search for entries on a specific date, use the &lt;em&gt;To&lt;/em&gt; field only.
		&lt;input type=&quot;submit&quot; value=&quot;Search&quot; name=&quot;searchBtn&quot; id=&quot;searchBtn&quot; /&gt;&lt;br clear=&quot;all&quot; /&gt;
	&lt;/fieldset&gt;
&lt;/form&gt;
&lt;div id=&quot;gridBlock&quot;&gt;
	...
&lt;/code&gt;

Looking at our demo grid, I only truly have two fields to search on: &lt;em&gt;Title&lt;/em&gt; and &lt;em&gt;Release Date&lt;/em&gt;. So, we provide for searching against our &lt;em&gt;Title&lt;/em&gt;, and for searching within a date range. To top off our simple search form, let&apos;s turn those &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; fields into &lt;a href=&quot;http://www.jqueryui.com&quot; target=&quot;_blank&quot;&gt;JQueryUI&lt;/a&gt; &lt;a href=&quot;http://jqueryui.com/demos/datepicker/&quot; target=&quot;_blank&quot;&gt;DatePicker&lt;/a&gt; fields.

&lt;h4&gt;jqGridDemo.js - DatePicker initialization&lt;/h4&gt;

&lt;code&gt;
$(&apos;input.addDatePicker&apos;).datepicker({
	showOn: &apos;button&apos;,
	buttonImage: &apos;/resources/images/icons/calendar.png&apos;,
	buttonImageOnly: true,
	dateFormat: &apos;mm/dd/yy&apos;
});
&lt;/code&gt;

This adds a DatePicker element to any input with the &lt;em&gt;addDatePicker&lt;/em&gt; class. At some point you&apos;ll want to add some range validation (client and server side).

For the moment the &lt;em&gt;action&lt;/em&gt; attribute is blank. That&apos;s OK, for us, as we&apos;re going to provide a custom submit handler in our script:

&lt;h4&gt;jqGridDemo.js - Search Form Submit Handler&lt;/h4&gt;

&lt;code&gt;
$(&apos;form#searchForm&apos;).submit(function(ev){
	ev.preventDefault();
	// something will go here
	return false;
});
&lt;/code&gt;

Next, we&apos;re going to think about how we&apos;re using our &apos;search&apos;. Basically, this is a filter we&apos;re going to apply through our query: a list of fields and values to narrow our result set by set criteria. We can param all our fields in our remote method (and should), so to avoid confusion we&apos;re going to &apos;scrub&apos; our form prior to making our ajax request. Basically, we don&apos;t need anything that&apos;s empty, or with a value of &apos;0&apos;.

&lt;h4&gt;jqGridDemo.js - scrubSearch&lt;/h4&gt;

&lt;code&gt;
var scrubSearch = function(){
	var frm = $(&apos;form#searchForm&apos;).serializeJSON();
	for(var i in frm){
		var val = frm[i];
		// if value has no length, remove the key
		if(val.length === 0){
			delete frm[i];
		}
		if(!isNaN(val-0) &amp;&amp; parseInt(val) === 0){
			delete frm[i];
		}
	}
	return frm;
};
&lt;/code&gt;

&quot;Wait a minute, Cutter. &lt;a href=&quot;http://www.jquery.com&quot; target=&quot;_blank&quot;&gt;JQuery&lt;/a&gt; doesn&apos;t have a &lt;em&gt;serializeJSON&lt;/em&gt; method.&quot; No, it doesn&apos;t. JQuery has &lt;a href=&quot;http://api.jquery.com/serializeArray/&quot; target=&quot;_blank&quot;&gt;serializeArray&lt;/a&gt;, for pulling form values out, but doesn&apos;t have a nice method for pulling that into object notation, which is easier to work with. &lt;a href=&quot;http://arjen.me&quot; target=&quot;_blank&quot;&gt;Arjen Oosterkamp&lt;/a&gt; posted this little plugin, in the comments of the &lt;em&gt;serializeArray&lt;/em&gt; documentation. While good, the one fault I had was that it didn&apos;t turn repeating field name (like checkbox usage) values into a list, which is standard behavior on a form submit, so I modified his work to accommodate.

&lt;h4&gt;jqGridDemo.js - serializeJSON&lt;/h4&gt;

&lt;code&gt;
// Before your document ready statement
(function( $ ){
	$.fn.serializeJSON=function() {
		var json = {};
		jQuery.map($(this).serializeArray(), function(n, i){
			(json[n[&apos;name&apos;]] === undefined) ? json[n[&apos;name&apos;]] = n[&apos;value&apos;] : json[n[&apos;name&apos;]] += &apos;,&apos; + n[&apos;value&apos;];
		});
		return json;
	};
})( jQuery );
&lt;/code&gt;

By applying this method to our form, we get a nice object that we can then loop through for value comparisons. We return the object after we&apos;ve removed any keys with empty or &lt;em&gt;0&lt;/em&gt; values. Since form values are strings by default, we have to work a little magic for finding numeric values (JQuery 1.7 includes the new &lt;a href=&quot;http://api.jquery.com/jQuery.isNumeric/&quot; target=&quot;_blank&quot;&gt;$.isNumeric()&lt;/a&gt; method, but we aren&apos;t using 1.7 in our examples).

Now, on first look you might think we&apos;re going to call this from within our form&apos;s submit handler, but that&apos;s not the case. Our example is using a basic &lt;em&gt;html&lt;/em&gt; page, but you might be using a dynamic page where you may pre-populate your form fields with data passed in the initial page request, to pre-filter grid results for some reason or another. For this reason, you would want to have this method called immediately on page load, and on any additional request as well. For this, we&apos;ll go back to our &lt;em&gt;populateGrid&lt;/em&gt; method.

&lt;h4&gt;jqGridDemo.js - populateGrid&lt;/h4&gt;

&lt;code&gt;
var populateGrid = function (postdata) {
		$.ajax({
			...
			data: $.extend(true, {}, postdata, {search: $.toJSON(scrubSearch())}),
			...
	};
&lt;/code&gt;

We used JQuery&apos;s &lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;$.extend()&lt;/a&gt; method to create a new &lt;em&gt;data&lt;/em&gt; object, combining our &lt;em&gt;postdata&lt;/em&gt; with a new object including &lt;em&gt;search&lt;/em&gt;. JQuery (I wish I knew why) does not include anything for converting an object to a JSON string (only the reverse, with &lt;a href=&quot;http://api.jquery.com/jQuery.parseJSON/&quot; target=&quot;_blank&quot;&gt;$.parseJSON()&lt;/a&gt;), so we must include another plugin library for making this possible. Luckily there&apos;s the &lt;a href=&quot;http://code.google.com/p/jquery-json/&quot; target=&quot;_blank&quot;&gt;jquery-json&lt;/a&gt; project on Google Code, which is heavily influenced by work done at &lt;a href=&quot;http://www.json.org&quot; target=&quot;_blank&quot;&gt;JSON.org&lt;/a&gt;. All we need, to access the &lt;em&gt;$.toJSON()&lt;/em&gt; method, is to add the file to our html head.

&lt;h4&gt;index.html - header script includes&lt;/h4&gt;

&lt;code&gt;
...
&lt;script type=&quot;text/javascript&quot; src=&quot;/resources/scripts/jquery-plugins/jqgrid-4.3.1/js/jquery.jqGrid.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/resources/scripts/jquery-plugins/jquery-json/jquery.json-2.3.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/resources/scripts/custom/jqGridDemo.js&quot;&gt;&lt;/script&gt;
...
&lt;/code&gt;

By handling this, in this fashion, the form&apos;s contents are taken into account on every grid load request. This means that paging and sorting requests will have the filter criteria, until such time as the form is cleared. It also means that our form&apos;s submit handler becomes that much simpler.

&lt;h4&gt;jqGridDemo.js - Search Handler figure 2&lt;/h4&gt;

&lt;code&gt;
$(&apos;form#searchForm&apos;).submit(function(ev){
	ev.preventDefault();
	grid.trigger(&apos;reloadGrid&apos;);
	return false;
});
&lt;/code&gt;

This is great! When you submit the form the grid&apos;s contents are now filtered by your search criteria. The only thing you have to do now is have a way to &apos;clear&apos; your search criteria. You can easily do this by adding a &lt;em&gt;reset&lt;/em&gt; button to the form, and binding to the reset event.

&lt;h4&gt;index.html - Search Form Buttons&lt;/h4&gt;

&lt;code&gt;
...
&lt;input type=&quot;submit&quot; value=&quot;Search&quot; name=&quot;searchBtn&quot; class=&quot;searchFormBtns&quot; /&gt; 
&lt;input type=&quot;reset&quot; value=&quot;Reset&quot; class=&quot;searchFormBtns&quot; /&gt;&lt;br clear=&quot;all&quot; /&gt;
...
&lt;/code&gt;

&lt;h4&gt;jqGridDemo.js - Search Form Reset Handler&lt;/h4&gt;

&lt;code&gt;
$(&apos;form#searchForm&apos;).bind(&apos;reset&apos;,function(ev){
	setTimeout(&quot;$(&apos;#gridTest&apos;).trigger(&apos;reloadGrid&apos;);&quot;,1);
});
&lt;/code&gt;

Our binding needs us to give the browser a moment to &apos;clear&apos; the field values, prior to us triggering a grid reload. Since &lt;em&gt;setTimeout&lt;/em&gt; will have no concept of scope, we cannot use our &lt;em&gt;grid&lt;/em&gt; variable here.

This all takes care of things, from an interface perspective, but we still need to handle these filter requests at the server. We&apos;re going to first change our remote method signature to accept our new &lt;em&gt;search&lt;/em&gt; parameter, which is now included on every request as a JSON string.

&lt;h4&gt;Entries.cfc - getEntries Method Signature&lt;/h4&gt;

&lt;code&gt;
function GetEntries(numeric pageIndex = 1, numeric pageSize = 50, string sortCol = &quot;ID&quot;, string sortDir = &quot;desc&quot;, string search = &quot;&quot;) {
&lt;/code&gt;

We can then test the argument for value, and &lt;em&gt;param&lt;/em&gt; all our search fields

&lt;h4&gt;Entries.cfc - getEntries figure 2&lt;/h4&gt;

&lt;code&gt;
function GetEntries(numeric pageIndex = 1, numeric pageSize = 50, string sortCol = &quot;ID&quot;, string sortDir = &quot;desc&quot;, string search = &quot;&quot;) {
	...
	if(Len(ARGUMENTS.search) AND IsJSON(ARGUMENTS.search)){
		ARGUMENTS.search = DeserializeJSON(ARGUMENTS.search);
	} else {
		ARGUMENTS.search = {};
	}

	param name=&quot;ARGUMENTS.search.title&quot; default=&quot;&quot;;
	param name=&quot;ARGUMENTS.search.from&quot; default=&quot;&quot;;
	param name=&quot;ARGUMENTS.search.to&quot; default=&quot;&quot;;
	...
}
&lt;/code&gt;

This now gives us some things to key off of for building our &apos;filtered&apos; query. Parts of this are fairly simple: If the field exists, add the filter to the query, and the param to the query definition. The &lt;em&gt;title&lt;/em&gt; is a good example.

&lt;h4&gt;Entries.cfc - getEntries figure 3&lt;/h4&gt;

&lt;code&gt;
...
// Main data query
LOCAL.sql = &quot;SELECT	SQL_CALC_FOUND_ROWS id,
				title,
				posted,
				views
			FROM	tblblogentries
			WHERE 0 = 0
			 &quot;;
if(Len(ARGUMENTS.search.title)){
	LOCAL.sql &amp;= &quot; AND title LIKE :title
	 &quot;;
}
LOCAL.sql &amp;= &quot;ORDER BY #LOCAL.orderby#
			 LIMIT	:start,:numRec&quot;;
LOCAL.q = new Query(sql = LOCAL.sql);
LOCAL.q.addParam(name = &quot;start&quot;, value = (ARGUMENTS.pageIndex-1) * ARGUMENTS.pageSize, cfsqltype = &quot;cf_sql_integer&quot;);
LOCAL.q.addParam(name = &quot;numRec&quot;, value = ARGUMENTS.pageSize, cfsqltype = &quot;cf_sql_integer&quot;);
if(Len(ARGUMENTS.search.title)){
	LOCAL.q.addParam(name = &quot;title&quot;, value = &quot;%#ARGUMENTS.search.title#%&quot;, cfsqltype = &quot;cf_sql_varchar&quot;);
}
...
&lt;/code&gt;

The &lt;em&gt;Release Date&lt;/em&gt; stuff is a bit more tricky, as you have to think about how dates are treated. First, you may not need to worry about working with the &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; fields at all. We can do a little pre-check right after our &lt;em&gt;param&lt;/em&gt; statements.

&lt;h4&gt;Entries.cfc - getEntries figure 4&lt;/h4&gt;

&lt;code&gt;
...
LOCAL.hasFrom = Len(ARGUMENTS.search.from) AND IsDate(ARGUMENTS.search.from);
LOCAL.hasTo = Len(ARGUMENTS.search.to) AND IsDate(ARGUMENTS.search.to);
...
&lt;/code&gt;

This allows us to verify that a value was passed, and that the string is a valid date value. Next we have to consider our logic. We stated on our form that the user can search for a specific day by only filling the &lt;em&gt;To&lt;/em&gt; field. This means that, at the least, we need to have value in the &lt;em&gt;To&lt;/em&gt; field to filter &lt;em&gt;Release Date&lt;/em&gt;.

&lt;h4&gt;Entries.cfc - getEntries figure 5&lt;/h4&gt;

&lt;code&gt;
// Main data query
LOCAL.sql = &quot;SELECT	SQL_CALC_FOUND_ROWS id,
				title,
				posted,
				views
			FROM	tblblogentries
			WHERE 0 = 0
			 &quot;;
if(Len(ARGUMENTS.search.title)){
	LOCAL.sql &amp;= &quot; AND title LIKE :title
	 &quot;;
}
if(LOCAL.hasTo){
	LOCAL.sql &amp;= &quot;AND posted BETWEEN :from
	 AND :to
	 &quot;;
}
&lt;/code&gt;

What you see here is that we&apos;ve added an &lt;em&gt;AND BETWEEN&lt;/em&gt; clause to the query if &lt;em&gt;to&lt;/em&gt; is passed in. But, why &lt;em&gt;BETWEEN&lt;/em&gt;? The &lt;em&gt;posted&lt;/em&gt; field, in our database, is a &lt;em&gt;DATETIME&lt;/em&gt; datatype. So, for instance, you searched for entries posted on &lt;em&gt;08/01/2011&lt;/em&gt; you would actually need to search the database for anything posted &lt;em&gt;BETWEEN&lt;/em&gt; 00:00:00 and 23:59:59 of 08/01/2011. We need to handle either a range, or a single date. The basic sql is the same (&lt;em&gt;AND BETWEEN&lt;/em&gt; statement), so what we have to concern ourselves with is how we create our &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; sql paramaters.

&lt;h4&gt;Entries.cfc - getEntries figure 6&lt;/h4&gt;

&lt;code&gt;
if(LOCAL.hasFrom AND LOCAL.hasTo){
	LOCAL.q.addParam(name = &quot;from&quot;, value = CreateODBCDateTime(ARGUMENTS.search.from), cfsqltype = &quot;cf_sql_timestamp&quot;);
	LOCAL.q.addParam(name = &quot;to&quot;, value = CreateODBCDateTime(ARGUMENTS.search.to &amp; &quot;23:59:59&quot;), cfsqltype = &quot;cf_sql_timestamp&quot;);
} else if (!LOCAL.hasFrom AND LOCAL.hasTo){
	LOCAL.q.addParam(name = &quot;from&quot;, value = CreateODBCDateTime(ARGUMENTS.search.to), cfsqltype = &quot;cf_sql_timestamp&quot;);
	LOCAL.q.addParam(name = &quot;to&quot;, value = CreateODBCDateTime(ARGUMENTS.search.to &amp; &quot;23:59:59&quot;), cfsqltype = &quot;cf_sql_timestamp&quot;);
}
&lt;/code&gt;

&lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-6deb.html&quot; target=&quot;_blank&quot;&gt;CreateODBCDateTime&lt;/a&gt; will create a sql date object format that the JDBC connector will properly convert for it&apos;s db and datatype. Thing is, when given a date, without time, then the date defaults to &lt;em&gt;{ts &apos;yyyy-mm-dd 00:00:00&apos;}&lt;/em&gt;. For this reason, our &lt;em&gt;to&lt;/em&gt; value must add on the time to the last second of that day, to properly search any entries through that day. The says if a &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; were passed, then filter between the beginning of &lt;em&gt;from&lt;/em&gt; and the end of &lt;em&gt;to&lt;/em&gt;, else if only &lt;em&gt;to&lt;/em&gt; was passed, then filter from the beginning of &lt;em&gt;to&lt;/em&gt; to the end of &lt;em&gt;to&lt;/em&gt;.

The last thing to notice in these blocks of code is the concatenation of the &lt;em&gt;LOCAL.sql&lt;/em&gt; string that builds our query. You may notice, in looking at these code samples, that there appears to be an additional line added to each. This is to accomodate a bug in ColdFusion&apos;s scripted sql parser, in &lt;a href=&quot;http://www.cutterscrossing.com/index.cfm/2011/11/14/A-Scripted-Query-Param--Whitespace-Gotcha&quot;&gt;dealing with whitespace when using sql parameters&lt;/a&gt;. If you look at this code with whitespace characters being shown, you will see the additional spaces required.

&lt;div style=&quot;text-align:center;&quot;&gt;
	&lt;img src=&quot;/images/jqGridDemo-pt5.png&quot; /&gt;
&lt;/div&gt;

And that&apos;s it! Now, when you submit search criteria, your grid will be filtered on the information you&apos;ve sent, and retain your criteria across paging criteria until you clear the search form.

&lt;div style=&quot;text-align:center;&quot;&gt;
	&lt;object classid=&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot;&gt;
        &lt;param name=&quot;movie&quot; value=&quot;/images/jqGridDemo-Search.swf&quot; /&gt;
        &lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;
        &lt;param name=&quot;bgcolor&quot; value=&quot;#FFFFFF&quot; /&gt;
        &lt;param name=&quot;flashVars&quot; value=&quot;width=815&amp;height=700&quot; /&gt;
        &lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt;
        &lt;param name=&quot;scale&quot; value=&quot;showall&quot; /&gt;
        &lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot; /&gt;
        &lt;embed allowFullScreen=&quot;true&quot; allowScriptAccess=&quot;always&quot; bgcolor=&quot;#FFFFFF&quot; quality=&quot;high&quot; scale=&quot;showall&quot; src=&quot;/images/jqGridDemo-Search.swf&quot; type=&quot;application/x-shockwave-flash&quot; flashVars=&quot;width=815&amp;height=700&quot; height=&quot;700&quot; width=&quot;815&quot; /&gt;
    &lt;/object&gt;
&lt;/div&gt;

That&apos;s it for now. In our next post we&apos;ll finally get around to those icons in the &lt;em&gt;Action&lt;/em&gt; column. Example code for this post may be found in the &lt;b&gt;Download&lt;/b&gt; link below.
				</description>
				
				<category>ColdFusion</category>
				
				<category>JQuery</category>
				
				<category>Development</category>
				
				<category>jqGrid</category>
				
				<pubDate>Fri, 13 Jan 2012 14:20:00 -0400</pubDate>
				<guid>http://www.cutterscrossing.com/index.cfm/2012/1/13/Intro-to-jqGrid-Part-5-Some-Other-Stuff</guid>
				
				
				<enclosure url="http://www.cutterscrossing.com/enclosures/jqGridDemo-pt5.zip" length="2251877" type="application/zip"/>
				
			</item>
			</channel></rss>
