Submit your widget

Using form labels as text field values jQuery

Created 14 years ago   Views 7119   downloads 1522    Author Alen Grakalic
Using form labels as text field values jQuery
View DemoDownload
84
Share |

The problem

Let's rethink what I just did. I placed a sentence "Input your email here" as a text field value by adding it to the VALUE attribute. Why is that wrong? The VALUE attribute of the INPUT tag should be used as a default value of the text field, not as a text field's description. The sentence I used is clearly a description and it should be used as a label (of course using LABEL tag). The correct way to use VALUE attribute for text fields is to input something meaningful, something that user might actually write himself (or herself). i.e. if you are logged in as member here on Css Globe and you wish to comment, you will notice that your email is set as a default value of an email text field in the comment form.
How will I find semantically correct way to place the labels (descriptions) into text field? JavaScript of course. It will help me to move stuff around without jeopardizing accessibility. Remember, the aim here is to have meaningful and accessible html code plus to have a usable form that fits the provided design.
Let's begin with markup. It should look something like this:

<form id="contactForm" action="/" method="post">
 
 <fieldset><legend>Contact Form</legend>
  <p>
   <label for="contact_name">Input your name here</label>
   <input type="text" name="contact_name" id="contact_name" value="" size="30"  />
  </p>
  <p>
   <label for="contact_email">And email address please</label>
   <input type="text" name="contact_email" id="contact_email" value="" size="30"  />
  </p> 
  <p>
   <label for="contact_message">Send us a couple of words</label>
   <textarea id="contact_message" name="contact_message"></textarea>
  </p>                 
  <p class="submit">
   <button type="submit" title="Send your message">Send!</button>
  </p>
 </fieldset>
 
</form> 

 

LABEL tags must have FOR attributes defined otherwise they don't make much sense plus this script won't work :)

Time to move it to the script. When dealing with this issue I came up with the script that automatically searches for LABEL tags, finds related INPUT (includes only text fields) based on a definition of FOR attributes and inputs the LABEL tag's content into the text field using VALUE attribute. How's that different from the straightforward non-semantic solution from the beginning of this article, you'll say... Well, take a look at the form markup again. This form is accessible and semantically correct to begin with. JS disabled browsers will still have meaningful interpretation of this form.

Lets see the script already

This is and unobtrusive JavaScript code powered by fabulous jQuery. You don't have to understand jQuery to use this form (but still this script requires it), I will try to explain each line. Here's the entire thing:

this.label2value = function(){ 

 var inactive = "inactive";
 var active = "active";
 var focused = "focused";
 
 $("label").each(function(){  
  obj = document.getElementById($(this).attr("for"));
  if(($(obj).attr("type") == "text") || (obj.tagName.toLowerCase() == "textarea")){   
   $(obj).addClass(inactive);   
   var text = $(this).text();
   $(this).css("display","none");   
   $(obj).val(text);
   $(obj).focus(function(){ 
    $(this).addClass(focused);
    $(this).removeClass(inactive);
    $(this).removeClass(active);          
    if($(this).val() == text) $(this).val("");
   }); 
   $(obj).blur(function(){ 
    $(this).removeClass(focused);              
    if($(this).val() == "") {
     $(this).val(text);
     $(this).addClass(inactive);
    } else {
     $(this).addClass(active);  
    };    
   });    
  }; 
 });  
};
$(document).ready(function(){ 
 label2value(); 
});

 

As you may notice from the code I have added css classes and attached some behavior to the fields to make a complete solution. Let's take it step by step.

$(document).ready(function(){
 label2value();
});

 

This initiates the script called label2value (that's our script here :) ) on page load using jQuery's $(document).ready function. First lines in our function:

var inactive = "inactive";
var active = "active";
var focused = "focused";

 

define the variables containing class names that we will use to style 3 states of the text field or text area:

  1. Inactive state - default state with no input from the user. With this state the label text inside the text field is used.
  2. Active state - when user provides some input and clicks away from the text field (on blur)
  3. Focused state - when user clicks on the field (on focus)

Classes should be styled to your preferences, in external css file or inside a STYLE tag on the document.
Moving on:

$("label").each(function(){
 obj = document.getElementById($(this).attr("for"));
 if(($(obj).attr("type") == "text") || (obj.tagName.toLowerCase() 

 

These lines basically select each LABEL tag and find matching text field or textarea based on the FOR attribute of the LABEL tag.

$(obj).addClass(inactive);
var text = $(this).text();
$(this).css("display","none");
$(obj).val(text);

 

Then it assigns default state class name to the text field, hides the label, gets the text from the label and puts it into text field.

$(obj).focus(function(){ 
 $(this).addClass(focused);
 $(this).removeClass(inactive);
 $(this).removeClass(active); 
 if($(this).val() == text) $(this).val("");
}); 

 

On focus function (when user clicks on the text field) changes the class name and if the user haven't provided any text, it clears the field.

$(obj).blur(function(){ 
 $(this).removeClass(focused); 
 if($(this).val() == "") {
 $(this).val(text);
 $(this).addClass(inactive);
 } else {
 $(this).addClass(active); 
 }; 
});

 

On blur function (when user clicks out from of field) checks if user has provided some input and if so it assigns active class name. If user left the field blank, script switches back to default mode with initial text and initial (inactive) class name.