Automating Placeholder Text In HTML Forms

Relates to Accessibility and DOM Scripting

One of the stumbling blocks for achieving Triple A Conformance of the WCAG 1.0 is Checkpoint 10.4 regarding placeholder text for form controls:

Until user agents handle empty controls correctly, include default, place-holding characters in edit boxes and text areas.Checkpoint 10.4 Web Content Accessibility Guidelines 1.0

This is actually an interim solution to accomodate certain legacy assistive technologies that can not handle empty form controls. However, accessibility can be improved if, in meeting this checkpoint, the placeholder text is informative text that assists the user with the information they should enter. For example:


<input type="text" id="name" name="name"
       value="Please enter your name"/>
<input type="text" id="tel"  name="tel"  
       value="Your Phone Number - 01234 123123"/>

This information can be valuable to the user where a complex form is layed out with tables and the label may be detached from the field it relates to. To ease the form completion process a Javascript event may be attached to the form field to clear the placeholder text when focus is received.


<input type="text" id="name" name="name"
       value="Your name"/
       onfocus="if(this.value=='Your name')this.value=''"/>

With a multi-field form the inclusion of a large number of onfocus event handlers will bloat the HTML so this behaviour should be defined in a separate script file.


var helpers = ['Please enter your name', '…', … ];
function addFieldListeners() {
  var elems = document.forms[0].elements;
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].type == "submit") {continue;}
    elems[i].onfocus = function(evt) {
      evt = (evt) ? evt : 
                    (window.event) ? window.event : null;
      if (evt) {
        var elem = (evt.target) ? evt.target : 
                    (evt.srcElement) ? evt.srcElement : null;  
        if (elem) {
          var value = elem.value;
          for (var i = 0, m = helpers.length; i < m; i++) {

            if (value == helpers[i]) {
              elem.value = "";
            }              
          }
        }
      }
    }    
  }  
}

Here an anonymous function is assigned to each form field and when focus is recieved the value is tested against an array of predefined placeholder text strings. This code could be cleaned up by assigning a new array search function to the Array object prototype property, and a global function for retreiving the element that received the event (since other behaviour in the document may require this). This solution will suffice, with new placeholders just added to the helpers array, but in larger projects this in itself can become quite a tiresome process - take a content management system as an obvious example.

Working on a CMS solution just the other day I thought about using the title attribute of the input field to store the placeholder text. My initial thinking was that this could still provide the helper information to the user after they had set focus on the field. If they were jumping around a large form, the user should not be expected to remember the helper text once it has been cleared. Plus the purpose of the title attribute is to provide additional information for the element - exactly what the helper/placeholder text is doing in this scenario. So, this time, using the closure technique discussed previously, the following:


<input type="text" id="name" name="name"
          accesskey="n"
          title="Please enter your name" 
          value="Please enter your name" />

could be handled with the following field listener:


function FieldListener(elem) {
  this.elem = elem;
  this.helper = "";
  
  var me = this;
  
  this.init = function() {
    this.helper = this.elem.getAttribute('title');    
    // Scott Andrew's addEvent method at 
    // www.scottandrew.com/weblog/articles/cbs-events
    addEvent(this.elem, "focus", this.clear);
    addEvent(this.elem, "blur",  this.redisplay);
  }
  
  this.clear = function(evt) {
    if (me.helper == me.elem.value) {
      me.elem.value = "";  
    }
  }
  
  this.redisplay = function(evt) {
    if (me.elem.value == "") {
      me.elem.value = me.helper;  
    }  
  }
}

The FieldListener object stores the title attribute value in a member variable when it is instantiated, then when the field receives focus, the field value is compared against this member variable. Functionality can be extended by redisplaying the placeholder text if the field is still empty when the user moves focus elsewhere - the FieldListener.redisplay() function achieves this. This event listener can be bound to each form field (along with other behaviours - eg pseudo CSS, validation) as follows:


function register(collection) {
  var i, elem, listener;
  for (i = 0; elem = collection.item(i++); ) {
    if (elem.nodeName == "INPUT" && 
        elem.getAttribute("type") != "text")
        {continue;}
    listener = new FieldListener(elem);
    listener.init();  
  }
}
function __init() {  
  if (document.getElementsByTagName) {
    var input_flds = document.getElementsByTagName('input');
    register(input_flds);
    var textarea_flds = document.getElementsByTagName('textarea');
    register(textarea_flds);
  }
  else {    
    nastyHackToHandleNonW3CDom();
  }
}

// see Simon Willison's addLoadEvent entry at 
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
addLoadEvent(__init);  

An alternative function would need to be provided for legacy browsers that do not support DOM2 (Netscape 4.x, MSIE 4.x). Perhaps just selecting the placeholder text on field focus so the user can delete it if they wish to (DOMElement.select()) may suffice. To round off, this modular solution provides a simple automated approach to handling placeholder text that does not require the author to expicitly register the text within the Javascript code - the whole process is automated based on the value of the title attribute.

Posted on Thursday, Jul 01, 2004 at 16:34:43.

Comments on Automating Placeholder Text In HTML Forms (4)

α comment

Do you have a suggestion for a clever way of clearing the placeholder text before the form is submitted? so that field left blank by the user arrive at the server as blank instead of the placeholder text?

Posted by Craig
Thursday, Aug 12, 2004 at 20:35:19

β comment

IMO this should be handled by the server. Even if an event handler is defined to clear the fields before submission, the fields still have to be checked on the server in case the user did not have client side scripts enabled. So the check before submission is redundant….

If PHP is doing the processing, array_diff() - which preserves keys - is a good method to remove all fields from the $_POST var that have not been filled out.

eg array_diff($_POST, $helpers)

Then can glue back together with array_merge() before returning data to the browser…

Posted by Tom
Friday, Aug 13, 2004 at 04:44:50

γ comment

*eep* unencoded email addresses

I ended up loading them all into a php smarty config file. The goal was to get the strings entirely out of the php code and into the hands of the template designers. I ended up with approximately the same solution that you suggest. I am stripping the placeholder strings in the config file out of the $_POST data, and instead of an array merge, I have a default string set in the template to display the appropriate string from the config file if the php $_POST array is empty.

Thank you very much for a very well thought out script. It really is quite slick.

Posted by Craig
Friday, Aug 13, 2004 at 07:26:15

δ comment

Cheers Craig,

I have removed your email address - encoding is on a long to do list!

Posted by Tom
Friday, Aug 13, 2004 at 13:01:19

Breadcrumbs Trail

[ Home ] -> TW Blog -> Jul 04 -> Automating Placeholder Text In HTML Forms
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.156 seconds