ColdFusion 9 added some new functions for the html grid. I want to take a look at 2 of them today that will make your life a little bit easier. In this example we are going to create a grid and add a toolbar to the grid. In the toolbar we are going to add some buttons with event handlers.
First we need to create a grid to display our artists.
Then we use the ajaxOnLoad() method to call a function.
In ColdFusion 9.0.1 we have the ability to get the grids top toolbar. With the top toolbar we can now add elements to it. Finally we use another new function to show the toolbar.
And here is the final result
Just a side note, you can also do this for the bottom toolbar as well. Here is a list of all the new JavaScript functions for the grid.
I just wrapped up my 1st presentation at CFUnited. Thank you to everyone who attended it. I had some issues with it but hopefully anyone who attended still enjoyed it. If you click on the menu option you can download all of the code for the presentation.
Last night I was working on a Mobile application that gets is data via a web service. This web service returns JSON by turning a record set into JSON using the serlializeJSON() function that is built into ColdFusion.
Whenever I am dealing with JSON I like to validate it before I start using it in an application. A great resource for validating data is http://jsonlint.com/. The data I was trying to get just was not validating and we couldn't figure out why. It seem to keep complaining about the bio of the speaker. This data for this was produced by the end user. In the end Elliott realized that it was unsafe characters in the Bio that was throwing everything off. He used this code to fix the issue and the json was now validating.
I was going to explain how this works but my friend Ben Nadel has a whole post on this you should really check out. Basically all the code above is doing is removing an un safe character that does not fall in between the "safe" ascii codes of 1-127.
I can't believe cfunited is almost here! First off I had to change one of my topics at the very last minute. I would like to apologize to anyone that was interested in seeing my "Validation in ColdFusion" presentation but I had to pull it. In it's place is a presentation I gave at cfObjective, ColdFusion 9: A new way of building applications. I got some really good feedback from cfObjective and its going to be even better this time around. I also though that since 9.0.1 was just released we could hit some of those new features as well.
On another note I was giving some really exciting news this week. I will be doing a 10 minute spot during the keynote. I don't want to give anything away yet but its going to be fun. I am really excited about that and can't thank Adam Lehman enough for asking me to participate. So just to recap here is what my schedule looks like.
Wednesday 9:00 AM Keynote (9:00AM) (10 Minute Spot)
Thursday 2:45 PM ColdFusion 9: A New Way of Building Applications
Friday 10:00 AM Developing Web Applications for Mobile Devices
A friend was telling me about a question he saw on an exam and wanted to know my thoughts on it. The exam wanted you to write out the function in pseudo code first and then write it in Java and ColdFusion. The question was pretty basic but it was a good one to think about. Write a method that will accept a sentence as an argument. The method will take this string and reverse the order of the words in the argument.
So following our instructions the first thing we need to do is talk out our thought process for this method.
create a variable to hold our new string
Split the argument into words using a space as the delimiter
loop over out list of words
take the current word in the loop and prepend it to our new string
That was pretty easy and gives us some really straight forward instructions on how to create our method. First I will write the method in Java. Lucky for us Java has a wonderful class called StringTokenizer. This class will allow us to break our string into tokens and has convenience methods for looping over the tokens and getting the next token.
As you might know ColdFusion can leverage any Java class. Because of that our method in ColdFusion should look pretty much the same. If your not familiar with ColdFusion the init method is just a way for us to pass something into the Java constructor.
I was working on a new Android project tonight when I came across an issue. In this application I am going to read an RSS feed and parse it out into a list of entries. The 1st thing I decided to do is go out and find a library to do this. No point in reinventing the wheel right. After a little searching I came across a great library called ROME
I whipped up a quick example to read in the rss feed.
Unfortunately when I ran the example I got an error.
05-23 23:36:36.541: ERROR/AndroidRuntime(263): java.lang.NoClassDefFoundError: [Ljava.beans.PropertyDescriptor;
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.BeanIntrospector.getPropertyDescriptors(BeanIntrospector.java:39)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.ToStringBean.toString(ToStringBean.java:129)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.ToStringBean.toString(ToStringBean.java:116)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.ObjectBean.toString(ObjectBean.java:120)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.SyndCategoryImpl.toString(SyndCategoryImpl.java:90)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.EqualsBean.beanHashCode(EqualsBean.java:193)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.impl.ObjectBean.hashCode(ObjectBean.java:110)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.SyndCategoryImpl.hashCode(SyndCategoryImpl.java:80)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at java.util.HashMap.put(HashMap.java:393)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at java.util.HashSet.add(HashSet.java:95)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at java.util.AbstractCollection.addAll(AbstractCollection.java:77)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS092.createSyndEntry(ConverterForRSS092.java:50)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS093.createSyndEntry(ConverterForRSS093.java:37)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS094.createSyndEntry(ConverterForRSS094.java:58)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS090.createSyndEntries(ConverterForRSS090.java:79)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS090.copyInto(ConverterForRSS090.java:64)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS091Userland.copyInto(ConverterForRSS091Userland.java:49)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.impl.ConverterForRSS094.copyInto(ConverterForRSS094.java:47)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.feed.synd.SyndFeedImpl.(SyndFeedImpl.java:144)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:123)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at org.cfbloggers.android.ColdFusionBloggers.parse(ColdFusionBloggers.java:43)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at org.cfbloggers.android.ColdFusionBloggers.onCreate(ColdFusionBloggers.java:29)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.os.Handler.dispatchMessage(Handler.java:99)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.os.Looper.loop(Looper.java:123)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at android.app.ActivityThread.main(ActivityThread.java:4627)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at java.lang.reflect.Method.invokeNative(Native Method)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at java.lang.reflect.Method.invoke(Method.java:521)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-23 23:36:36.541: ERROR/AndroidRuntime(263): at dalvik.system.NativeStart.main(Native Method)
Of course I thought I was doing something wrong but it turns out I wasn't. I copied the same code over to a basic Java project taking Android out of the picture. The code ran as expected and at this point I was really confused. I did some searching and came across this article. Basically Android's version of Java has excluded some libraries from the language. One of those libraries is java.beans which the ROME project uses. So the error I was getting makes sense now and In the end I guess you just can't use ROME in an Android project. I will go on the hunt for another open source library that can parse a feed. If you know of one that will work with Android please let me know.
I am huge fan of ColdFusion Builder and I love how easy it is to create extensions. I decided today to create the ColdFusion Builder Extensions Development Google Group. This will be a group where we can discuss extension development. The idea to create this group came from the ORM dev group. That group is a great centralized location for ORM specific questions and I can see this group providing the same service. Please sign up for the group today and start asking questions.
Last night I released v 0.71 of Hyrule I thought I would take a couple minutes to walk through a couple of the changes that were made.
So first off we have a bug with the display property. IF you have been paying attention you should of seen a bunch of examples that look kind of like this.
When we get an error it will display an error message based on the default message template which looks like "notempty=The field {display} must contain a value.". In the case above it will replace {display} with the @display property. This is all great but what if you don't have a display property. Well what it should do is use the property name. It was not doing this so I fixed that part. Then my friend Tony said why not just humanize the property name. Great idea so thats what we are going to do now. The following will do the same as the example above.
The next problem I came across on my own. Take the following example. Now if you fill nothing in for all 3 properties your going to get back 3 errors. The first 2 because they are still empty and the 3rd because your empty string does not follow the rules of a phone number
This was obviously a problem. What if you just wanted to validate that if the user did enter a phone number that it was valid. It was because of this for validators like phone,ssn,credit card,etc... that we now check to make sure the property is not empty before we validate it. If you want to make sure the phone number has something in it and that its a phone number then you can do the following.
There were some other minor changes but that was the bulk of it. All of the unit tests were also updated to contain a testIsBlankReturnsTrue method. Let me know your thoughts on all of this and feel free to join the Google Group.
I thought I would take a few minutes and walk through my open source validation framework for ColdFusion. Below is a video that gives you a brief overview on the framework and I also walk though a couple examples. If you have any feedback on the framework, please let me know.
I am happy to announce that I have completely rewritten my Hyrule Validation framework. Thanks to some really great feedback from Lance Staples & Aaron Greenlee I decided that some issues needed to be fixed. The more I got into the framework the more I realized that I was not happy with a lot of things. First off I was not happy with the rules engine. The rules we basically doing validation and supplying an error message. A rule should only do one thing and that is validate the data. This made it much easier to write unit tests again. The framework now comes complete with unit tests for all of the rules which makes it a whole lot easier to test.
So what is Hyrule? Here is a short description from the documentation.
Validation has always been a tedious process that I wanted to rid my self of. I have used various frameworks that are out and many iterations of my own. I don't think you can really use other frameworks until you understand the problem and how the problem is solved. With that In mind I wanted to tackle my own validation framework. The idea for this framework really came from 2 sources. I really enjoyed the way the QuickSilver framework was using annotations in there framework so I thought I would do the same. The other source of inspiration was the hibernate validation frameowrk. That framework does the same thing for validation and many of my constraints, example and documentation text come from that framework.
Annotations are a very convenient and elegant way to specify invariant constraints for a domain model. You can, for example, express that a property should never be null, that the account balance should be strictly positive, etc. These domain model constraints are declared in the bean itself by annotating its properties. A validator can then read them and check for constraint violations
The plan is to write up many tutorials on how to use it. For now I just wanted to make everyone aware of the changes. Please download the framework and try it for yourself. Feedback like yours is priceless so anything you can provide would be a big help. Happy Validating!