Wednesday, September 24, 2008

*Update to previous post* CF-Ajax gets jealous

This post modifies the following previous post:

Create Spry Data Sets Using Inline Data

It turns out that the above doesn't work inside of a bound CFDiv. For instance, if your Spry dataset lives on a pages called data.cfm, and you include data.cfm on another page using a bound cfdiv, it breaks. For the below example, you can put the guts of my previous post on this subject (referenced above) into data.cfm if you want. See the example below:

<----------- data.cfm ----------->
...
Create a spry dataset
...
Show dataset in a dynamic region
...
<----------- End data.cfm ----------->


<----------- view_data.cfm ----------->
...
<cfdiv bind="url:data.cfm" />
...
<----------- End view_data.cfm ----------->


I have spent almost two entire days trying to get the above to work. Interestingly, my research into the above with FireBug shows that I can get it to actually create and populate the dataset. However, try as I might, I can't get the dynamic region in view_data.cfm to show any data. I have researched on the web, and found others with the same finding; for example:

Spry + CFDIV = No Love

I love the CF Ajax goodness, but this is very frustrating and a major limitation. It makes it so that I can't use Spry (and possibly other Ajax frameworks) on big apps that include CF-Ajax (especially bound cfdivs). I work for a government agency, and we write some very large, powerful, complicated apps using ColdFusion. If the CF-Ajax makes it so that I can't extend the CF goodness with other Ajax frameworks, then this is a problem

I am hopeful that Adobe will address these sorts of CF-Ajax quirks in CF 9. If they don't, I will probably think twice in the future about using the CF Ajax features in the future.

Tuesday, September 23, 2008

Create Spry Data Sets Using Inline Data

I finally figured out how to create a Spry dataset using inline data. This is a major step towards usability, and wasn't posted on any of the Spry examples that I searched thru on Adobe's site.

To create a Spry dataset using inline data, you can just create a javascript array, and give the array to the dataset object using the Data Set's setDataFromArray(array) function. I have tested it in both FireFox and IE. You can find more information about the setDataFromArray(array) fuction here: http://labs.adobe.com/technologies/spry/articles/data_api/apis/dataset.html#setdatafromarray

The example below uses ColdFusion syntax to get data from the database and to populate the array. However, this would work with whichever language you like, or even with static data. See the following example:

Example:

<cfquery name="get_users" datasource="ds">
SELECT last_name, first_name, phone, address
FROM user

</cfquery>

<script type="text/javascript" src="Spry_1_6_1_022408/includes/SpryData.js"></script>

<script>

user_array = [<cfloop query="get_users">{last_name: "#get_users.last_name#", first_name: "#get_users.first_name#", phone: "#get_users.phone#", address:"#get_users.address#"}<cfif currentrow="" neq recordcount="">, </cfif></cfloop>]

user_dataset = new Spry.Data.DataSet();

user_dataset.setDataFromArray(user_array);
</script>

<div id="users_region" spry:region="user_dataset">

<table border="1">
<tr>
<th spry:sort="last_name">Name</th>
<th spry:sort="phone">phone</th>
<th spry:sort="address">Address</th>
</tr>
<tr spry:repeat="personnel_dataset">
<td>{last_name}, {first_name}</td>
<td>{phone}</td>
<td>{address}</td>
</tr>
</table>

</div>

You may have noticed that the above example doesn't var scope its JavaScript variables. This was on purpose, and it will still work. Experience has shown that var scoping variables can make them incompatible with some of the ColdFusion 8 CF-ajax stuff.

Thursday, May 01, 2008

ColdFusion Ajax Functions

Tired of looking up the syntax for the ColdFusion 8.0 Ajax functions? Me too. So, I created the following. You can thank me later.

https://acrobat.com/#d=0xInJpmQt0NgwOGzthNHuQ

Monday, April 07, 2008

More JavaScript, More "duh"

Another JavaScript "duh" moment. (You can see my previous JavaScript "duh" moment from last week here: http://nm1m.blogspot.com/2008/04/javascript-duh-moment.html ). A lot of times I want links to fire off JavaScript events, but to still look / taste / feel like links. Previously I have done it like this:

<a href="#" onClick="ColdFusion.Window.create('etc', 'etc.cfm');">
The upshot to this technique is that you get a link that looks and acts like a link. The minus is that when you click it, it appends a hash mark (#) to the end of your url. Not a big deal, but still.

On Friday, at the fabulous Salt Lake RIA Dev Shed, I learned another little "duh" JavaScript technique. Rather than trying to explain it, I will just show. You can do the same thing as the above like this:

<a href="javascript:ColdFusion.Window.create('etc', 'etc.cfm';">

Huzzah for cheap little JavaScript tricks!

Tuesday, April 01, 2008

JavaScript duh moment

Ok, so, don't laugh. A few days ago I learned something about JavaScript. Something ridiculously basic. Something I should have known for a very long time, but didn't.

Like many Web Developers, I am entirely self-taught. I have never taken a class on Web Development, never formally studied JavaScript or DOM or any of it. Back in the day when I first learned JavaScript, I initially learned how to connect JavaScript to objects, triggered by events. For instance:

<input type="button" onClick="alert('button clicked.');">
Naturally, I assumed that all JavaScript had to be tied to an object. This can be a real pain when you want a JavaScript event to fire independent of any user events, for instance when the page loads. Sometimes you can just use the body tag's onLoad event, but this is not always practical or even possible.


Enter inline JavaScript. Turns out that the other day, I needed to fire a JavaScript event when an Ajax-powered div finished loading. Rather than try to set up events tied to some object in the loaded div page, I simply did the following:

<script>
document.write('text here');
</script>

And it worked. I had no idea that you can just write JavaScript to a page, and when the page loads in the browser, the JavaScript commands will iterate in the order they are encountered. Good to know. Very useful.

So, like I said, don't laugh. I have been doing this a long time, but never knew that you could just output JavaScript to a page, and it would just run, independent of user events. At the risk of seeming ignorant, I am posting this information out there so that if there are any other old-dogs out there who learned by doing, and don't know this basic behavior yet, now you know.

Thursday, March 27, 2008

CFEclipse Newbie questions answered

David McGuigan, member of the Salt Lake ColdFusion User Group has posted a useful list of CFEclipse newbie tips. If you use CFEclipse, you might find this list helpful.

You can find it here: http://www.slcfug.org/fusetalk/messageview.cfm?catid=5&threadid=639

Monday, March 03, 2008

Coldfusion Application Server service terminated with service-specific error 2

Sometime last week, one of our main ColdFusion servers needed a bit of a pick-me-up, and one of our server guys juiced it with 2 more gigs of RAM. After the new RAM was installed, I went into the ColdFusion administrator, and upped the MAX Heap Size. I changed it from 1024 to 2048 and saved. It gave me a polite message stating that the change would take effect after the ColdFusion server restarted. I moved on with life, not restarting the server or service at that time; the work day had begun, people were already hitting our server, best to leave well-enough alone.

This morning I checked the cool new ColdFusion Server Monitor included with CF8. I saw several hung threads, which are a sure sign that your server is inching towards becoming unresponsive (the more hung threads, the fewer resources available to working threads). I decided that rather than waiting for our server to stall in the afternoon, I would restart the ColdFusion service right then, and the hung threads would evaporate. So I did. And the service never restarted.

Our main server guy was out of town, and the other server guys were busy, so I dug in to try to figure out what was going wrong myself. I did some research.

In the Event Viewer, I found an error that looked something like this:

"Coldfusion Application Server service terminated with service-specific error 2"
A bit of time on Google taught me that one of the causes of this error is services starting too slowly. This can be mitigated by giving them more generous timeouts. For more information, see the below:

http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_18799

I did what it said there (adjusting for ColdFusion 8), restarted the server, and nothing changed. The ColdFusion service still didn't come up. By now I started to suspect that my JVM Heap changes of the previous week had precipitated the problem. Some more time spent with Google, and I found this useful link:

http://www.coldfusionmuse.com/index.cfm/2005/10/28/jvm.gc

This little gem teaches you how to go into the server's jvm.config and adjust JVM args directly, including the Max and Min Heap sizes. Server restart, and problem solved.

Tuesday, January 15, 2008

Getting dates to appear correctly in an HTML cfgrid

A little while ago, I posted this to my blog, however I didn't give much context, I just dumped a pair of links to fairly dense articles. What do these links tell you? They tell you how to have SQL Server format things for you (in this case dates), similar to using the dateFormat function in ColdFusion. This can come in very handy when working with cfgrids.

Although the Adobe livedocs say that you can mask / format values that go into a grid, I haven't had much success with getting it to work; especially in the case of HTML grids.

A great work-around is just to use the SQL Server CONVERT function. How? If you plug a date/time/timestamp column name into CONVERT, and tell it what you want to convert it to, it will change the data-type of the date/time column (just in the resulting recordset, not in the actual table) to the data-type of your choice, and format the date for you to one of many predefined formats. Lots of examples of this and other techniques here:

http://www.oreilly.com/news/sqlnut_1200.html

For a list of predefined formats, and some more (not very useful) examples, look here:

http://msdn2.microsoft.com/en-us/library/ms187928.aspx

So, if you need to use a date/time column in a cfgrid, just preformat it in the actual query like so:

SELECT CONVERT(VARCHAR(11), date_column, 102) AS formatted_date
FROM table
...etc.

I hope that makes more sense.

Wednesday, January 09, 2008

Binding to an HTML cfgrid

Wanna bind to an HTML cfgrid, and having trouble finding the correct syntax? Here it is:

bind="{gridName.columnName}"

I searched for a couple of hours, and could only find the flash forms syntax. Then I found it documented here:

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=ajaxui_5.html#1137151


Here is an example using cfinput to bind to the cfgrid :

<cfgrid name="user_grid" query="get_users">
<cfgridcolumn name="last_name">
<cfgridcolumn name="first_name">
<cfgridcolumn name="age">
</cfgridcolumn>

<cfinput type="text" name="the_last_name" bind="{user_grid.last_name}">

There you go. Enjoy.