Monday, January 30, 2012

Django Forms and jQuery UI Dialogs

It's difficult, at the best of times, to specify user interface behavior in HTML5-based front-ends.  That is, if we want to utilize the best new browser technology has to offer, we need to recognize and understand how to use it.  We could, however, simplify the matter greatly by simply using HTML5 and CSS3, without Javascript. Minimal Javascript interruptions in our user interface design eliminate the complexity by at least half.  Browsers don't work that way.  Applications built for the web don't work that way.  There is a world of rich interactivity that we'd be missing out on should we decide not to use any Javascript libraries out there.

This is where things get interesting because most browser vendors do a decent enough job of providing HTML5 support that we can actually realize some of their benefits without fear of standard support.  And now we're left with the challenge of figuring out how to best integrate some of the more useful HTML5 features into our web applications.  This is balanced against the fact that the Javascript libraries we've invested in take care of a lot for us.  The very challenges we've faced in the past with prior versions of the HTML standard aren't really hindrances anymore.

So to find some practical usage that your current Javascript library doesn't take care of, or doesn't do so optimally, we have to look at more than just the technologies sitting inside the browser.  We have to mesh our user interface patterns with those of the application serving up these pages so as to form a complete architecture.

Identifying Javascript Challenges
One hurdle I've had to overcome myself is forcing HTML5 capabilities where they aren't justified because the same capability already exists in the Javascript framework.  For example, HTML5 tries to address the common problem of validating user input.  This not only handy — your validation criteria go directly into the markup — but it's a standard way of doing validation that works in any browser. So, if I'm starting to write a new user interface, maybe this is the solution.  Maybe not.  In my case, this doesn't work for a couple reasons.

First, Javascript frameworks I use, and probably most useful Javascript frameworks in existence, do some sort of user input validation.  Now is the time to ask, do I really want to adopt the standard HTML5 way of doing user input validation at the browser level, or is what I have in place going to do the job well enough?

Second, what implications does adopting HTML5 standards have on your web application framework?  For example, what would you need to implement differently on the server — does your framework support the HTML5 functionality you're aiming to implement?  It's a similar situation to that of Javascript libraries that have solved some of the challenges that HTML5 have rectified.  Maybe your framework has already solved some particular issues common in several application domains. But does the web application server fit well with your Javascript?  Is there a pattern of behavior that the Javascript toolkit you're using provides that'll fit tightly inside your application?

An effective method of identifying Javascript challenges is to look not at the user interface code alone, nor the application framework code alone.  Look at how they work together.  If you're like me, there probably isn't a bundled solution that tackles all your requirements — something like that, something that addresses the problem of synchronizing using interface code and the communication with the web application itself.  In fact, bridging the implementation inside the browser with what you're building on the server is a prevalent design issue.  One that I'm not convinced will ever be standardized globally — there are simply too many problem domains, and too many configurations to support every possible scenario.  That's where you can utilize HTML5 as a bridge between the two.

Using Data Attributes
As simple as it may sound, data attributes are an elegant solution to some of the implementation challenges I've faced.  Take a simple example — a Django form. The Django form API allows me to deffer much of the form-handling tasks to the framework itself — presenting forms, validation, and so on.  Now suppose I want to present this form in a jQuery UI dialog.  That's easy enough to do for the most part, but I need to pass a few additional details to the dialog widget.

One thing I need to tell the dialog widget about are the buttons.  I'll typically have a button to submit the form, and a button to cancel the action and close the dialog. To set the labels for these buttons, all attach the text to the form itself — using HTML5 data attributes.  When it comes time to build the dialog widget, my Javascript code simply grabs these attributes — jQuery has a data API that'll make this easy.  But if this is just text we're setting, why not do it straight in the Javascript?  Well, if we're setting it in the template, we can utilize some of the rendering tools supplied through Django's template system — things like internationalization and other string formatting filters.

This might seem like a trivial matter — passing data from the web application framework to the Javascript presentation layer — but it's important to get it right. There are probably several ways of doing this correctly — for example, building an API for our Javascript code to query — but the template-to-Javascript method seems like the shortest path.  In the Django world, we're not limited to merely formatting strings and passing them along to the Javascript user interface, we can use other features pertinent to the user interface like URL formatting.  No matter the framework, using HTML5 data attributes to store meta-data about the user interface means we're able to bundle the web application with any number of web browser technologies in a cohesive way.