NCDevCon in Raleigh this past weekend went well. Dan Wilson, Jim Priest and many volunteers orchestrated a good conference for the second time. I think the fact that it is free to attendees testifies to what can be accomplished with a some hard work. It was really nice to see some new speakers and different topics represented also. A show of hands in a couple of sessions revealed that some participants were not ColdFusion developers, but either designers or developers with other languages.
The fact that sponsors also helped out with some basic costs speaks well of the quality of the conference. Other attendees that I talked to also felt as though it was well worth a weekend of their time to get some good training and networking. Good job and thank you to the Triangle Area CFUG.
I gave my talk on jQuery and AJAX Sunday afternoon. Although I was hoping for a bit more of a hands on type of workshop, it seemed to go well and I had some good feedback. After covering some jQuery basics, I demonstrated about six different use cases for jQuery and its built in AJAX capabilities. The source code, slides, and lesson demonstrations are all available at http://mattjanell.com/NCDevCon/. The "Get the Zip" link at the top includes the source code and slides. The slides are in Open Office format, which one person said he could open in PowerPoint.
Lesson 6 is a partially completed lesson. I told the class participants that their homework before the next NC Dev Con was to finish it out - sure they will :). All the code should be looked at as a starting point or example of how something can be done with jQuery. I owe a thanks to Ray Camden for his timely blog posts on jQuery and AJAX. I used a couple of those as starting points for my lessons.
Feel free to post any questions about the code samples.
I believe this behavior is as expected, however it can break code that worked in CF 8. Not so much break as in get errors, but you will get the wrong data, which is worse really. Similar issues have been discussed and maybe even raised on the bug tracker, but I didn't see an example quite like this, so I wanted to share.
Basically, when in a function and looping over a query or a list, you may reference a column name or the list index without adding a scope. For example, myQuery has a column named "key."
<cfset local.key = key>
On the first iteration through the loop, the variable local.key does not exist. The column "key" is found in the query, and now local.key equals that value; say it is 1. On the next loop iteration, CF sees that local.key indeed does exist and never looks to the query for the column "key." The scope hierarchy looks in LOCAL before it looks to the query we are looping over. So each subsequent assignment of local.key will equal 1.
There are several fairly simple workarounds: don't use the same variable name for the local scope; scope the right side of the assignment; etc. The point is you will need to watch out for this on legacy code.
See the enclosed file below ("Download Enclosure") for sample code.
Posted 5/20/10 @ 5:19 AM by Matt Williams
I'll be speaking this weekend at the North Carolina Developer's Conference (NCDevCon) about using jQuery and AJAX in Forms. It will be a hands on workshop so participants can learn by doing. It is geared toward the jQuery beginner. I have a few basic examples of jQuery and AJAX already, but would actually like some ideas from other people. If anyone has something they've seen or wanted to do and wondered how to do that in jQuery, please post it here and I'll see if I can incorporate it.
Since I'm concentrating on forms, I may include a jQuery UI element or two such as the autocomplete, datepicker or tabs. Some of those are not as ajaxy as others, but may be helpful.
Example code can be downloaded below (see Download Enclosure). See also: [ DEMO ]
To use the filter, define it in the <event-filters> section of your config.xml:
<event-filter name="BreadCrumbsFilter" type="CrumbsExample.filters.BreadCrumbsFilter">
<parameter name="HomeEvent" value="Home" />
<parameter name="HomeText" value="Home" />
<parameter name="TrailMax" value="6" />
HomeEvent is the name of your default or home event name.
HomeText can be something more user friendly. This is what will display in crumb trail.
TrailMax is arbitrary, but could be useful if you need it.
To have an evet show up in the crumb trail, within an <event-handler>, put this:
<parameter name="page" value="Home" />
<parameter name="isEntryPoint" value="true" />
The page parameter is what will be displayed in the crumb trail.
isEntryPoint is optional and defaults to false. Setting it to true will reset the trail and make that event the first in the trail (after Home).
The output can be found in the views\nav.cfm page. Put it where ever makes sense for your layout.
In the filter, you'll see some code referring to window number or "wn". This was my attempt to handle links that open new windows or tabs. I did not get too far with this and for now everything defaults to 1.
Feel free to ask questions here or on the email list.
Posted 8/29/08 @ 3:16 PM by Matt Williams
The past week or so I've been upgrading an app to Mach II version 1.6 and CF 8. The first task was to take advantage of cfthread for some auditing. Basically just like a hit counter we have an audit filter that logs when certain events are requested. This writes a record to the db and can easily be handled by a new thread since nothing after it is dependent on its completion.
To use cfthread I decided to try out the Publish-Subscribe Listener Method Invocation. It was easy enough to convert the filter to a listener by just changing some of the parameter references to event arg references. I then added a new <message-subscriber> block to replace the <filter>. Within that I specified multithreaded="true" and waitForThreads="false".
Then, in the events that previously had a <filter name="audit"> reference I changed that to <publish message="audit">. Any parameters that used to be sent to the filter via the <parameter> command can easily be changed to <event-arg> so the new listener can access it.
And that was all it took to take advantage of some threading. I didn't even have to learn the syntax and usage of cfthread. Maybe this is good, maybe not. I did look at how the Mach-II core files were doing it though, just out of curiousity.
Team Mach-II did a good job of wrapping up that functionality so that it can be used by other parts of the framework when appropriate.
I hope to blog some more about some of Mach-II's new features. I've also been trying to help out with some docs on the wiki, so check it out when you're ready for the new version.
Though this seems like a no-brainer, I want to blog it for future reference as it isn't something I do often enough to remember the solution. Perhaps others will find it useful too.
Basically I wanted to simultaneously run the trunk version and a branch version of the application I was working on. Before CF8, I had only been able to do one at a time and even then had to modify a mapping in the CF admin and restart CF services to switch between them.
To make this happen in CF8, I have the following 2 lines in my Application.cfc (inside a script block):
THIS.Name = "myApp_" & Hash(ExpandPath("."));
THIS.mappings["/myMapping"] = getDirectoryFromPath(getCurrentTemplatePath());
Now I can run both versions at the same time, allowing me to compare screens/data when needed. And I was able to remove the mapping definition in the CF Administrator.
Oh, and to credit people appropriately (although simple, I didn't come up with these myself)... If first found the second line on a couple of blogs, including these two. Then Peter Farrell suggested the first line to me on the Mach-II list.
Last summer I played with Fusion Debug when it first came out. I liked it but didn't have enough time to get a decent understanding. Then in October I won a license during a online training session. Unfortunately, due to moving, holidays, moving again, laziness, yadda yadda, I never even had time to install the full license. Since ver. 2 just came out, it was time.
It is sweet, I must say. It gives you so much info right in eclipse. And the ability to evaluate expressions and change variable values really rocks. I can't say enough good about this product. Oh, and the new install was a breeze. The old version made you go in and change some jvm settings deep in the heart of CF. And although the docs were excellent in walking you through this, how much easier it is to just confirm some directory paths in a wizard installer?
So I will be trying to rid myself of my bad cfdump/cfabort habits and using Fusion Debug. Oh and if you don't have a clue what I'm talking about, you can learn more and download a trial at their website. If you have 10 minutes, definitely check out the gettings started page. There you can see some short videos demonstrating some of the features. The coolest feature (in my opinion) is the one titled "Setting Variables and Watching Expressions".
First the about me. My last post (almost 3 months ago) mentioned me quitting. and starting my own business. I did quit, but accepted a full-time position with a different company. In addition, my wife and I decided to move to Kentucky. I am now working from home for a company in California. Enough about me...
As I do some retrofitting / migrating code from one app to another, I am thinking I like the use of named arguments when making a function call. The reason for this is primarily readability and the usefulness of it depends on the situation. For example, if I'm trying to track down what is going on in various function calls, the following is not very understandable:
<cfset callSomeMethod(argumentCollection=localStruct) />
Or possibly even less helpful:
<cfset callSomeMethod(1,'joe') />
Whereas this tells you exactly what is being passed without having to read additional code:
<cfset callSomeMethod(userID=localStruct.userID,moreData=localStruct.moreData) />
In some cases though, if you're needing just pass everything, then the first line of code probably makes more sense. While I find listing out the names of each parameter a bit cumbersome, I do think it helps when going back and trying to see what is going on.
Big thanks to Steven Erat, Charlie Arehart and the folks at Fusion Reactor for last week's CF Online Meetup. Charlie gave a great overview of Fusion Debug's capabilities. If you aren't familiar with Fusion Debug, check out the website. A couple of weeks ago I downloaded the trial and played around, but now I have to really dig in and learn how to use it. And if you aren't familiar with the CF Online Meetup group, check their site out.
Forget all the major feature type of stuff everyone is asking for in CF 8. I just want some minor conveniences...
<cfloop query="myQuery" GROUP="someField"> - So I don't have to close my <cfoutput> do a cfoutput just for grouping, then restart.
<cfset myVar += 1 /> - Minor, but would be more consistent with other languages...
Maybe I'll think of more later...