Design, etc. on a semi-daily basis.

Expanded Compact Accessible Forms with zem_contact_reborn

· Dec 14, 12:45 PM

zem_contact_reborn (hereafter ZCR) is possibly the most complete form mailer plugin to date for the excellent Textpattern blogging engine / CMS. The plugin smartly attaches semantic classes to its generated XHTML, facilitating styling of error messages, individual fields, etc.

However, these predetermined classes conflict with our modified compact accessible form method, which replaces classes. Replacing the class string gets rid of the plugin-generated classes, undoing the ability to (for instance) style label elements generated in an error (ZCR supplies a class of “zemRequirederrorElement”). We need the ability to add or remove classes to an arbitrary list of other classnames. Particletree outlines just the thing here:

  1. String.prototype.trim = function() {
  2. return this.replace( /^\s+|\s+$/, "" );
  3. }
  4. function addClassName (elem, className) {
  5. removeClassName (elem, className);
  6. elem.className = (elem.className + " " + className).trim();
  7. }
  8. function removeClassName (elem, className) {
  9. elem.className = elem.className.replace(className, "").trim();
  10. }

In the previous article, we first apply the “overlabel-apply” style to label elements that already have the class of “overlabel”. Since ZCR doesn’t (yet) allow you to specify classes on generated label elements, we’ll just have our script attach itself to all label elements in the form. Comment out the following line like so:

// if (labels[i].className == ‘overlabel’) {

And be sure to comment out the corresponding closing brace, of course.

This may cause trouble if you’re employing labels next to checkboxes, select elements or other non-text-entry fields, but since this is just an extension of a principle developed for compact forms, I’m sure you’ll act with discretion.

Note: Since we’ve now done away with the need for “overlabel”, I shortened “overlabel-apply” to “applied” for a bit of economy.

Now instead of changing className we’ll append another class to the className string. This is an easy modification for the first two functions:

  1. // Change the applied class to hover the label over the form field.
  2. addClassName(labels[i], 'applied');
  3. // labels[i].className = 'overlabel-apply';
  4. // Hide any fields having an initial value.
  5. if (field.value !== '') {
  6. addClassName(labels[i], 'filled');
  7. // hideLabel(field.getAttribute('id'), true);
  8. }

We now need a swap function to hide/move the label when the field is focused, and replace it if the field is blurred and empty. Once again, we have to precisely add or remove a className; replacing the entire class=”“ string isn’t an option.

The previous swap was originally:

labels[i].style.textIndent = (hide) ? '-1000px' : '0px';

which we then had modified to

labels[i].className = (hide) ? 'overlabel-apply filled' : 'overlabel-apply';

We’ll use the same ternary notation with a bit of rearrangement to evaluate the true/false condition and manipulate className, like so:

(hide) ? addClassName(labels[i], 'filled') : removeClassName(labels[i], 'filled');

See it in action.

And there you have it. Compact form aesthetic, accessibility retained, style abstracted to the CSS, and compatible with preexisting classes on your label elements. Happy compacting.

The blog. And stuff.

We'll have comments enabled shortly eventually.

del.icio.us/simmer

flickrd

coming soon