How I Learned To Stop Worrying And Love Inheritance

So for the last month or so (and for at least another couple of weeks to come) I’ve had my nose to the grindstone on what’s likely to become the primary project management tool for my current employer. It brings a lot of changes to the table for us (consolidating client, project, module, and user management into a single area, granting limited (secured) access to clients and their customers, incorporating hooks for a lot of planned new functionality to come, to name but a few) but one of the bigger departures is a move from a scattered and only weakly-enforced MVC format to a much cleaner (and more PHP-like) OOP structure in a tightly-enforced MVC format with most of the core functionality abstracted away in a series of classes from the hands of future junior devs and dabbling execs with coding privileges. As much a change in our standard coding practice as in the core architecture itself.

Setting that up made for the perfect excuse to do something I’ve wanted to try out for awhile: take advantage of CF9/Railo 3.2 and throw tags out the window altogether to move into all-script CFCs. On top of that, most of the existing ‘OOP’ architecture was little more than a collection of (undocumented) function libraries, so this seemed like a good time to force a move to JavaDoc-style notation and better OOP as well. Got data that multiple sub-modules need to keep straight? Make it a property of the core class. Want a bunch of methods available to the sub-modules but don’t want to keep rewriting it? Standard inheritance has your back. Et cetera. Good times.

What started as a few core modules ballooned into an ever-growing series of classes, subclasses, and utility libraries, and it only hit me belatedly that while there was a shell of a front-end interface waiting for the back-end to be completed, I hadn’t actually tried running any of them yet—unit testing is still on my Things-To-Start-Doing list, unfortunately. In front of me was a shiny (and mostly empty) display page, waiting for the refresh that would actually initialize the class at the end of a complex chain. Any errors in any of the other linked classes, properties, or methods would spell ruin for this page until fixed…

Sure enough, refresh was clicked, and the 500 error page appeared with a lengthy stacktrace. A long list of java.lang.StackOverflowErrors alternating between the parent class (ConsoleManager) and one of the new utility classes (Validate). Long-suffering sighs were made, code was delved into, names were desultorily changed in case I’d accidentally used a reserved term in a method or class name. No dice.

And then, on closer inspection, the culprit stood out plainly. In the parent consoleManager class:


component displayname="ConsoleManager" {
...
/**
* A reference to the super-module's custom DB validation library
**/
this.Validate = new ccc.console.validate();
...
}

And at the start of the Validate utility class:

component displayname="Validate" extends="ccc.console.consoleManager" {
...
}

The light dawned. Facepalm time. Custom methods within the Validate class were performed on the same core database referenced as a property in the ConsoleManager class, so initially Validate was set up to simply extend ConsoleManager and thus inherit those properties. But then Validate was needed for other sub-classes of ConsoleManager, so it seemed only logical to store an instance of it in ConsoleManager in the same way. Thus the eternal loop; ConsoleManager is instantiated, attempts to instantiate the Validate class, which is a child of ConsoleManager and thus instantiates another ConsoleManager, et cetera ad infinitum (or at least until stackOverflowError).

In the end, the database reference simply became an init() argument in Validate’s constructor function (passed in by ConsoleManager on instantiation) and no more extension was needed. The loop was broken, and many lessons were learned about class inheritance, the importance of test-driven development, and the pitfalls of too much uninterrupted coding.

Field Notes: the ‘form’ attribute

illustration of the HTML5 form attribute

The humble form attribute at play

There are dozens of attributes, input types, and APIs in the HTML5 spec, and it seems like more show up on our radar and in our readers every day. If you’ve been alive anytime in the last three years, you’re probably already familiar with some of them, like search and email inputs or the File API. I’ve noticed that one, though, keeps getting overlooked: the humble ‘form’ attribute. No surprise there; it’s not flashy, doesn’t make any visible changes, and doesn’t add any seriously new functionality to the game. But it’s not without a few use cases of its own.

The Back-Story

This is one I stumbled across accidentally in mid-March of 2011, when it was first being pushed out in FF4 (Chrome and IE had not yet caught up). For some arcane reason having to do with a legacy datepicker plugin (well before jQuery UI solved all our problems), certain inputs in one of our applications had an extra form="theform" attribute—unsemantic and certainly not a valid attribute at the time, but apparently it did what it was supposed to do (whatever that was). All of a sudden, our Firefox users were seeing that input’s values disappear in transit. One minute a valid date was entered, the next we got an application exception email about referenced values missing from the URL scope. And only in Firefox, the browser I’d been pushing our clients (mostly IE7-8 users) heavily towards.

After a fair number of hours and a lot of exploratory surgery on our elements, we finally found the culprit. The ‘form’ attribute, previously a non-player, was suddenly doing something: blocking that input from submitting with the rest of the form. Pretty soon we realized why: the form tag had no ID, much less an ID of ‘theform.’ Firefox was scraping the DOM for an entity to handle the input data which didn’t exist. So we deleted the attribute and business carried on as usual. But it left me thinking.

Why It’s Useful

Think about it: a perfectly valid, script-free way to put form elements—any form element in fact—outside their parent <form> tag, while still including their values on form submission.

"But why would I have orphaned form elements?" I hear you ask. How about this: the design for a product page calls for user input in multiple locations around the page, each in their own block level sections. Sure, you could keep them all in the same form and just use CSS to position them around the page, but what if the elements vary by product or by user? Say you’re loading dynamic content which may include elements to a form on your page. Or multiple forms, if it’s a complex page. You could wrap the whole content pane in the form element. Or you could just include the form’s ID in the elements’ ‘form’ attribute and save yourself the hassle.

Or, for those with simpler tastes, you can have all the submit buttons you like for a given form anywhere on the page with absolutely no javascript. Surely that could come in handy.

Here’s a demo for your testing pleasure.

Still not convinced? Here’s where it gets interesting. The ‘form’ attribute can, in theory, accept a list of space-separated IDs belonging to one or more forms the input’s value gets submitted with. In other words, one form element belonging to multiple forms at once.

The Upsides

  • Flexibility. Did I mention it’s not just for <input> tags? Sure, it works with the full range of HTML5′s many input types, but you can also stick it on textareas, selects, buttons, and even fieldsets!

The Downsides

  • Compatibility. In this case, it’s pretty well supported across desktop and mobile browsers, with one exception (which I bet you can guess). True to form, Internet Explorer remains the major holdout even as of version 10, so anyone using this attribute will have to use a javascript polyfill to support IE users. Sigh. Still, if that’s the only problem, then it’s not so much of a downside, right?
  • Full feature support. So maybe I overstated things just a teensy bit when I said this is well supported. Truth is, it works in nearly everything but IE, but with a catch: so far, none of the browsers I’ve tested actually allow the multiple form IDs as has been suggested. In fact, the current draft of the spec doesn’t actually allow for multiple values. Whether this is likely to stay that way is anybody’s guess, but there’s always hope.