Example E

Complete Well-Behaved Dynamic Label Script

This page demonstrates our completed script.

It is well-modularized, doesn't exclusively bind to event handlers, degrades nicely when JavaScript is not available, and doesn't couple to the processing of the form.

It is based on the same, simple HTML code:

  <form>
    <label for="username" class="dynamicLabel">Username</label>
    <input type="text" id="username" name="username" />
  </form>

But we've modified the JavaScript to dynamically output the CSS and initialize the script only when our minimum requirements are met:

  <script type="text/javascript">
    if (supportsDynamicLabels()) {
      document.writeln('<style type="text/css">');
      document.writeln('label { display:none; }');
      document.writeln('</style>');

      addEvent(window, "load", setupLabels);
    }

    function setupLabels() {
      var objLabels = document.getElementsByTagName("LABEL");
      var objField;

      for (var i = 0; i < objLabels.length; i++) {
        if ("dynamicLabel" == objLabels[i].className) {
          objField = document.getElementById(objLabels[i].htmlFor);
          addEvent(objField, "focus", focusDynamicLabel);
          addEvent(objField, "blur", blurDynamicLabel);
          objField._labelText = objLabels[i].firstChild.nodeValue;
          objField.value = objField._labelText;
        }
      }

      for (var i = 0; i < document.forms.length; i++) {
        addEvent(document.forms[i], "submit", resetLabels);
      }
    }

    function resetLabels(event) {
      var elm = getEventSrc(event);
      var objLabels = elm.getElementsByTagName("LABEL");
      var objField;

      for (var i = 0; i < objLabels.length; i++) {
        if ("dynamicLabel" == objLabels[i].className) {
          objField = document.getElementById(objLabels[i].htmlFor);
          if (objField._labelText == objField.value) {
            objField.value = "";
          }
        }
      }
    }

    function addEvent(objObject, strEventName, fnHandler) {
      if (objObject.addEventListener)
        objObject.addEventListener(strEventName, fnHandler, false);
      else if (objObject.attachEvent)
        objObject.attachEvent("on" + strEventName, fnHandler);
    }

    function focusDynamicLabel(event) {
      var elm = getEventSrc(event);
      if (elm._labelText == elm.value) {
        elm.value = "";
      }
    }

    function blurDynamicLabel(event) {
      var elm = getEventSrc(event);
      if ("" == elm.value) {
        elm.value = elm._labelText;
      }
    }

    function getEventSrc(e) {
      if (!e) e = window.event;

      if (e.originalTarget)
        return e.originalTarget;
      else if (e.srcElement)
        return e.srcElement;
    }

    function supportsDynamicLabels() {
      return document.getElementById && (window.attachEvent || window.addEventListener);
    }
  </script>