Wednesday, November 3, 2010

jQuery Plugin for HTML5 Form Validation

As I have posted previously, I like to write User Interface Libraries.  An important part of each library I have written in the past has been the JS layer as it adds the interactivity to the entire experience.  The problem with my past attempts has always been how tightly coupled every component was.  If you make a change in one component, you risk breaking any or all other components.

In my most recent attempt at a UI lib, I have decided to break out different layers of the library into their own library.  Aside from the obvious decoupling, this allows each library to evolve separately and with this, I hope to reach a much wider audience as no one would be forced to use a big library if they only wanted one or two features. This will also be my first time releasing any of my code to the public, so lets hope 11 years of internal development has paid off :)

I would like to start by saying that the functionality being added to forms in HTML5 is long overdue.  I mean we have had to deal with a lack of a required attribute for far too long now.  And no maxlength on a textarea... what were they thinking? :)

Each UI lib I have built in the past has made an attempt to fill this void and typically has fallen short in some manner or another.  But now with the HTML5 spec getting closer to final, the spec in general receiving so much attention, and at least one browser or another attempting to add some support, this makes writing a UI lib to meet this demand that much easier.  The W3C spec provides "the spec"; you know that document we always request when starting a project but rarely receive other than a few emails of the idea persons rants or a couple chopped up screenshots thrown together in MS Paint. Yeah, those specs! :)  I'm not saying that's what the W3C spec doc is like...cause its actually a good spec doc.. honest.  And having at least one browser or another that has attempted to implement some of this functionality helps set a precedence for how it should function in the UI lib for the other browsers.  It might not be how all browsers end up implementing in the end, but at least it sets us in the right direction.

So enough build up!  I am presenting an early release of the jquery-ui-form.js library!  This is a jQueryUI plugin using $.widget that adds ui.form and ui.field widgets.  I started off with Web Forms by Scott Gonzalez and reorganized the code into a $.widget because I thought it fit better that way and I added much more on top of that.  This is an early release so not everything is finished yet as the $.form widget does not do anything yet.

It is, however, very functional in regard to the ui.field widget.  It provides support for HTML5 input attributes: [required], [placeholder], [max], [min], [pattern], and [step], HTML5 select attributes: [required] and HTML5 textarea attributes: [required] and [maxlength].  It provides validation for typeMismatch, rangeUnderflow, rangeOverflow, stepMismatch, tooLong, patternMismatch, and valueMissing.  It also adds methods for checkValidity(), setCustomValidity(), validationMessage(), validity(), willValidate(), labels(), valueAsDate(), valueAsNumber(), stepUp(), and stepDown() but not all are complete yet in this release.  I have also added some extra validation attributes on input and textarea for [data-minlength] along with a tooShort validity check and on select-multiple type for [data-max] and [data-min] which use the rangeUnderflow and rangeOverflow validity checks.

All functionality attempts to work along side, rather than instead, of existing HTML5 features that browsers have already implemented.  So in other words, if your browser already supports the feature, the lib will use it.  Otherwise, it attempts to provide a substitute.  The [placeholder] attribute is a very good example as detection is done on whether the browser supports this natively.  If it does, the lib does nothing, otherwise we provide an alternative to mimic how it works in other browsers.

As this is setup as a $.widget, it is accessible like any other jQueryUI widget.  You can initialize the widget simply by using:

$('#myField').field();

Or on all of your form elements by using:

 $(':input').field();

You can access methods by using:

$('#myField').field('checkValidity');

You can change any of these constraint attributes using normal jQuery attr() and the change is reflected in the validation immediately:

$('#myField').attr('max', 100);

I'll be providing more docs, etc about the library as I finish more on the project page.  In the meantime, please download and try this out and let me know what you think, good or bad.  Any feedback is good feedback.

Tuesday, August 31, 2010

User Interface Libraries

I have been all about the UI/UX in my work now for the past 4 years or so.  The biggest hurdle of course was the cross-browser compatibility issues.  Way back when I first got into standardizing UI's, I built my own javascript cross-browser library (ouch!).  It was painful, but worked through a lot of those pesky issues.  The original purpose of it was to make AJAX standard across browsers but soon turned into much more.

Then I discovered all these people who had more time on their hands that already did that work for me and I soon scrapped that idea of reinventing the wheel and used my first third-party JS library.  I built a JS library on top of prototype.js that suited the needs of the project.  I then moved onto MooTools and did the same by building my JS library on top of it.  This time though, I threw in some CF custom tags that generated the markup for some common UI components and then initialized them from my JS library.

This vicious cycle of building UI libraries has continued.  I think I am now on number 4.  I have moved onto jQuery now for my 3rd and 4th libraries which is definitely a keeper.  However now I build my JS lib as a jQuery plugin which makes it much easier to integrate, implement, and upgrade.

My 4th installment I am building myself on my own time so for the first time ever, I will actually be able to share it with the world.  I plan on putting it on Google Code when it gets to a good point.  I have to say this time around, I think I really nailed it!  I have learned a lot from each version I have written.

In my 4th version, I am still using jQuery (as I mentioned) and using jQueryUI as well.  I have created CF custom tags as wrappers to jQueryUI components.  The custom tags simply create the markup required for the UI component.  My library plugin once loaded simply scans the page for any components and calls the appropriate jQueryUI class passing in any config.

Another thing I try to accomplish with my UI library is ensuring it takes advantage of HTML5.  Especially the new form controls.

The thing I did differently with this version over my 3rd was rather than duplicating all the attribute logic in each custom tag, I moved all logic into CFC's.  So basically the custom tags are do nothing more than instantiate a CFC passing all attributes.  The CFC takes care of validation the attributes; ensuring all required are passed, ensuring they have proper enumerated values, etc.   Using CFC's came in very handy so I could add inheritance to the tags.  Some of my tags are just wrappers with additional attributes to other tags.  This got sloppy when all logic was in the tags, but by using CFC's, this was a piece of cake.

Anyway when I release this one I'll explain more.  Until then...

Creating Date from Epoch

I have worked with dates in ColdFusion for as long as I remember.  But recently I have realized that CF is very limited in allowing you to create dates from what are considered standard representations of dates in other programming languages.

So let us see...
I have now() which only gives me the current date/time.
I have createDate/createDateTime() which takes 3/6 arguments.

That's it!  Well what about Epoch AKA numeric date?  Come on Adobe, where is my createDate(milliseconds) function?

Well anyway, I could not live without a way to create dates from Epoch as I find this to be the best way of passing date/time objects between server and client and even other server-side languages.

Through some research I found where using the dateAdd() function to accomplish this, and the examples I found all used Epoch seconds which worked fine.  However, I wanted to use Epoch milliseconds which dateAdd() has a problem with.  The 2nd argument in dateAdd() takes an integer and milliseconds is a long which very quickly threw a nice CF error for me :)

So I figure since Java very easily allows us to create a date object this way, lets take advantage of that.

createObject('java', 'java.util.Date').init(javaCast('long', milliseconds));

And now, lets turn this into a simple reusable custom function.  Fortunately, the type="numeric" of <cfargument> does accept a long.


<cffunction returntype="date" name="createNumericDate" output="false">
<cfargument type="numeric" name="milliseconds" required="true" />
<cfscript>
return createObject('java', 'java.util.Date').init(javaCast('long', arguments.milliseconds));
</cfscript>
</cffunction>

And there you have it.  The simplest way I could find to create a date in CF from Epoch milliseconds.

OWASP's CF ESAPI

So a little while back, I took an interest in the OWASP website.  I soon realized they provided API's with a lot of their recommendations already built for any one to use in their projects.  My dreams of simple security implementation were soon crushed when I discovered the ColdFusion version of their Enterprise Security API (ESAPI) was never finished.

I got in contact with the project lead who informed me that he no longer had time to work on it and was looking to pass it off.  So I set out to finish this API myself.  I started off with what was already done, but soon scrapped it in favor of mirroring what the Java version of the API was doing.

I have now been working on this in my spare time for awhile now and I have to say, I am quite happy with myself.  I have the authentication and authorization pieces working.  I am currently working on the encoding functionality which I recently decided that using some of the Java API's functionality was necessary in order to accomplish string manipulation in a timely manner.  Thank you, JavaLoader :)

I have not at this point pursued taking over as lead to the CFESAPI project.  I am waiting until I have something a little more solid before entering that realm.

And in the beginning...

So I'm finally going to do it.  I'm going to start posting to a blog.  This will be my first time so be gentle.

Why?  Why did I finally decide to start blogging?  I've been pondering the idea for quite some time but I am very busy with work and family so dedicating time to write about what I've been working on has not been a priority.  I have so many ideas of things I would like to work on and so many cool things that I actually do get to work on, I figure its best I share some of those with the world.

What finally pushed me over the edge and into blogging?  I do a lot of research online in order to keep up-to-date with my field and more and more I am now seeing how employers are using blogs of developers to assist in the screening process for employment.  Now I am not currently seeking other employment but should the need arise in a few months or years, I figure it would be good to have a well established blog of what I have been doing to help secure that future dream job.

So.. I'm off! Let's see how this goes!