Client-side validation for the new Symfony forms with jQuery

The new Symfony forms are great improvement over the old forms and once you get over the learning curve you can’t imagine life without them. The only problem with them is that they don’t really offer client-side validation (yes, being agnostic when it comes to Javascript libraries is maybe good but come on). There is fortunately a plugin that does client-side validation but it is Prototype-based, and looks a bit clunky.

For those of us using jQuery there was nothing, so we decided to write our own small helper that integrates this jQuery validator with the new forms. It’s nothing fancy, but it does the trick for now, and we may expand it into a full-fledged plugin that does all sorts of crazy things.

Using the helper:

  1. Download and install the jQuery validation plugin.
  2. Download the helper and put it in lib/helper/jQueryValHelper.php
  3. Include the jQueryVal helper.
  4. To enable the helper for a specific form:
    <?php echo jquery_val_form_tag($form, array(‘action’ => url_for(“@register) ))?>

That’s it.

The validator currently supports email, min and max length validation. The only required option is action, the other options you can pass it are:

  1. error_placement: Change where the errors are rendered, for example:
    'error_placement' => 'error.prependTo(element.parent().next())'
  2. error_element: Change the element used to render the errors, default is label.

All other options you pass are added to the form as attributes.

Playing with appjet

The other day one of my friends jokingly mentioned that he thought strippers were being “marginalized” as profession. I thought this was funny, so I leveraged the powers of the internet to prove to him that in fact strippers are less marginalized then say podiatrists.

Enter amimarginalized.com

Anyway, with all of the hub-dub about Javascript being the next “big thing” I decided to give appjet a whirl. Appjet allows developers to develop and deploy server side Javascript applications. Additionally, appjet recently released “appjet in a jar” which lets users deploy the appjet platform on a different server.

Getting the appjet platform up and running was really simple. I already had Java 6 installed on one of our servers so all I had to do was download the appjet jar and fire it up with “java -jar appjet.jar”

In general, getting things moving was pretty easy with appjet. It also just “feels” natural to write Javascript for the client and the server. Switching between client and server is done with a comment directive:

/* appjet:client */
/* appjet:server */

appjet also provides a special directive for CSS styles:

/* appjet:css */

The other feature I really liked about appjet is its support for printing HTML elements. Appjet comes with a tag library that makes creating HTML tags particularly simple. The syntax looks something like this:

print(

FORM({action:"/", method:"get", onsubmit: "javascript: return submitJob()"},
SPAN({id: "job-label"}, "Job Title: "),
INPUT({text:"text", name:"jobField", id: "jobField"}),
INPUT({type:"hidden", name:"isPost", id: "isPost", value: "1"}),
INPUT({type: "submit", value: "Submit"})
)
);

And boom you have a XHTML compliant form.

The other neat feature, (from the appjet docs) is that “You can also treat a tag like a JavaScript array (it has all the same methods) and add to it programmatically.” so something like this works:

var list = UL();

list.push(LI("One item"));
list.push(LI("Two item"));

["Red","Blue"].forEach(
function(color) {
list.push(LI(color+" item"));
}
);

printp("The following "+list.length+" items may be of interest.");
print(list);

I was also really impressed with the appjet persistent storage system. The platform lets you persist arbitrary Javascript objects in “collections” that can then be iterated, filtered, and sorted. On amimarginalized.com I have about 800 elements loaded up and it seems to perform reasonably well.

The one issue I have with the storage library is that there isn’t any way to just load a bunch of data into the system. You can only load data from inside an appjet script file. The problem I ran into is that I hit the Java 64kb file size limit pretty quickly. It would be really awesome if the JAR had some functionality to load up say a file full of JSON objects.

All and all, using appjet has been a positive experience. It was really easy and fun to build an “easy” app using it. I’d really like to know some more about how appjet is put together but the documentation is sparse. The only information I could find was the logos on the download page. They suggest that appjet is composed off AppJet, Rhino, Jetty and of course Java. I’d be interested to know if there are any plans to expose JVM libraries to appjet code. It seems like this would allow the platform to quickly gain extensive library support – including the JDBC.

Anyway, the amimarginalized.com site uses “advanced” algorithms to determine how marginalized your career is. It just counts the number of results on Yahoo BOSS for the job you enter and compares it to a set of about 800 saved jobs.

You can download the source code here.