Popup Error Example 5: aria-labelledby attribute used for error message

Features

  • aria-labelledby attribute is used to label form control and includes element with error message.
  • HTML5 required attribute to identify a form control is required.
  • aria-invalid="true" attribute is used to identify a form control has an invalid value, otherwise the attribute is removed for compatibility with Firefox.
  • role="status" is used to autmatically announce errors in form controls.

Pizza Order Form

Name
Address
Phone
Delivery Method
Crust
Thin
Classic
Deep Dish
Toppings
Sausage
Pepperoni
Mushrooms
Onions
Green Peppers
Back Olives
Extra cheese

HTML Source Code


  <h2>
    Pizza Order Form
  </h2>
  <div class="text">
    <div id="id-name-label">
      Name
    </div>
    <input id="id-name"
         required="true"
         type="text"
         size="30"
         aria-labelledby="id-name-label id-name-error"
         onblur="checkName()">
    <span id="id-name-error"
        class="noerror"
        role="status">
    </span>
  </div>
  <div class="text">
    <div id="id-address-label">
      Address
    </div>
    <input id="id-address"
         required="true"
         type="text"
         size="40"
         aria-labelledby="id-address-label id-address-error"
         onblur="checkAddress()">
    <span id="id-address-error"
        class="noerror"
        role="status">
    </span>
  </div>
  <div class="text">
    <div id="id-phone-label">
      Phone
    </div>
    <input id="id-phone"
         required="true"
         type="text"
         size="14"
         aria-labelledby="id-phone-label id-phone-error"
         onblur="checkPhone()">
    <span id="id-phone-error"
        class="noerror"
        role="status">
    </span>
  </div>
  <div class="select">
    <div id="id-delivery-label">
      Delivery Method
    </div>
    <select id="id-delivery" aria-labelledby="id-delivery-label">
      <option>
        Eat in store
      </option>
      <option>
        Pickup
      </option>
      <option>
        Home delivery
      </option>
    </select>
  </div>
  <div class="group">
    <div id="id-crust" class="title">
      Crust
    </div>
    <div class="button">
      <input id="id-thin"
           name="crust"
           type="radio"
           value="Thin"
           aria-required="true"
           aria-labelledby="id-thin id-crust">
       Thin
    </div>
    <div class="button">
      <input id="id-classic"
           name="crust"
           type="radio"
           value="Classic"
           aria-required="true"
           aria-labelledby="id-thin id-crust">
       Classic
    </div>
    <div class="button">
      <input id="id-deep"
           name="crust"
           type="radio"
           value="Deep Dish"
           aria-required="true"
           aria-labelledby="id-thin id-crust">
       Deep Dish
    </div>
  </div>
  <div class="group">
    <div id="id-toppings" class="title">
      Toppings
    </div>
    <div class="button">
      <input id="id-sausage"
           name="topping"
           type="checkbox"
           value="Sausage"
           aria-labelledby="id-sausage id-toppings"
           aria-describedby="id-special">
       Sausage
    </div>
    <div class="button">
      <input id="id-pepperoni"
           name="topping"
           type="checkbox"
           value="Pepperoni"
           aria-labelledby="id-pepperoni id-toppings">
       Pepperoni
    </div>
    <div class="button">
      <input id="id-mushrooms"
           name="topping"
           type="checkbox"
           value="Mushrooms"
           aria-labelledby="id-mushrooms id-toppings">
       Mushrooms
    </div>
    <div class="button">
      <input id="id-onions"
           name="topping"
           type="checkbox"
           value="Onions"
           aria-labelledby="id-onions id-toppings">
       Onions
    </div>
    <div class="button">
      <input id="id-green"
           name="topping"
           type="checkbox"
           value="Green Peppers"
           aria-labelledby="id-green id-toppings">
       Green Peppers
    </div>
    <div class="button">
      <input id="id-black"
           name="topping"
           type="checkbox"
           value="Black Olives"
           aria-labelledby="id-black id-toppings">
       Back Olives
    </div>
    <div class="button">
      <input id="id-x-cheese"
           name="topping"
           type="checkbox"
           value="Extra Cheese"
           aria-labelledby="id-x-cheese id-toppings">
       Extra cheese
    </div>
  </div>
  <input type="submit"
       value="Submit Order"
       onclick="submitOrder(event)">

CSS Source Code


   div { border: solid medium transparent; } div.focus { border-color: black; background-color: #FFFFA0; } div.hover { border-color: black; background-color: #EEEEEE; } input[type="text"]:focus, select:focus { background-color: #FFFFA0; outline: medium solid black; } input[type="text"]:hover, select:hover { background-color: #EEEEEE; outline: medium solid black; } div#id-errors { color: red; display: none; margin-left: 1em; border: thin solid red; width: 25em; } div#id-errors a { color: red; } h2, h3 { margin: 0; padding: 0; margin-top: 1em; } div.text, div.select, div.group, input[type="submit"] { margin-top: 0.5em; } div.group { width: 20em; } div.group div.title { font-weight: bold; } span.error { color: red; border: thin solid red; padding: 0.25em; } span.noerror { color: transparent; border: thin solid transparent; padding: 0.25em; }

Javascript Source Code


   // Focus styling code $(document).ready( function() { $('input[type="radio"]').focus(function() { $(this).parent().addClass('focus'); }); $('input[type="radio"]').blur(function() { $(this).parent().removeClass('focus'); }); $('input[type="radio"]').parent().hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); }); $('input[type="checkbox"]').focus(function() { $(this).parent().addClass('focus'); }); $('input[type="checkbox"]').blur(function() { $(this).parent().removeClass('focus'); }); $('input[type="checkbox"]').parent().hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); }); }); // // Scripting for submit button form validation function moveFocus(id) { $('#'+id).focus(); } function clearErrorFeedback() { $('div#id-errors').empty(); $('div#id-errors').css('display', 'none'); } function exampleErrorFeedback(errors) { var num_errors = errors.length; str = (num_errors === 1 ? "1 Error\n" : num_errors + " Errors\n"); $('div#id-errors').css('display', 'block'); $('div#id-errors').append('<h2><a id="id-errors-start"></a>' + str + '</h2>'); var messages = "<ol>\n"; for (var i = 0; i < num_errors; i++) { var e = errors[i]; messages += '<li><a href="#' + e.id + '" onclick="moveFocus(\'' + e.id + '\')">' + e.message + '</a></li>\n'; } messages += "</ol>\n"; $('div#id-errors').append(messages); moveFocus("id-errors-start"); } // // Scripting for inline form validation function checkItem(id, flag, message) { var em = $('#' + id + '-error'); $(em).empty(); var ei = $('#' + id); if (flag) { $(ei).attr('aria-invalid', 'true'); $(em).append(message); $(em).removeClass('noerror'); $(em).addClass('error'); } else { $(ei).removeAttr('aria-invalid'); $(em).addClass('noerror'); $(em).removeClass('error'); } } function checkName() { var ei = $('#id-name'); checkItem('id-name',($(ei).val().length === 0), "Name cannot be empty! Enter your name"); } function checkAddress() { var ei = $('#id-address'); checkItem('id-address',($(ei).val().length === 0), "Address cannot be empty! Enter your address"); } function checkPhone() { var ei = $('#id-phone'); var phone = $(ei).val(); if (phone.length === 0) { checkItem('id-phone',true, "Phone cannot be empty! Enter your phone number"); } else { p = ""; for (var i = 0; i < phone.length; i++) { var c = phone[i]; if ((c >= "0") && (c <= "9")) { p += c; } } checkItem('id-phone', ((p.length !== 7) && (p.length !== 10)), "Not a valid phone number, use this format (111) 222-3333"); } }