TextBox Watermark using HTML5 and jQuery

A ‘TextBox Watermark’ is an UI effect that is often employed in space constrained scenarios where putting in a label next to a text box explaining the purpose of the textbox is not possible. In such scenarios, the TextBox has a watermark that stays on till a user starts typing. For example the WordPress.com home page

wordpress

Here when we start typing on the Username or the Password textbox, the text vanishes allowing you to put in your username and password

wordpress-login

Apart from the above use case, it is often used to show sample data or expected formatting. This effect has become so popular that it is now supported in HTML5 <input> elements through an attribute called ‘placeholder’. But like all things, not all browsers support HTML5 yet. The following html

textbox-watermark

gives us the following out put on IE9, Firefox 12 and Chrome 19.

ie9-watermark-nosupport

As we can see above, IE9 does not support this effect.

To get the same effect across all browsers we will develop a small jQuery plugin that will take the placeholder value provided and applies the watermark effect across all browsers.
Creating the Plugin
We will go step by step on how to create the jQuery Plugin.

Step 1: Basic Syntax

jQuery plugins are JavaScript function properties added to the jQuery.fn object from the jQuery library. The syntax for it is as follows:

jQuery.fn.inputWatermark = function() 
{
    // The plugin related methods here  
};

As we see above, inputWatermark is the name of our plugin. You can replace it with a name of your choice for the plugin.

Step 2: Using the $ symbol

Now we can wrap the above in an immediately invoked function expression (IIFE) so that it maps to the $ sign and it can’t be overwritten by another library in scope of its execution. So our boilerplate code becomes


(function ($) 
{
    $.fn.extend({
        inputWatermark: function() {  
        // The plugin related methods here  
      }
    });
})(jQuery);


Step 3: Maintaining Chainability

We want our plugin to be applicable to multiple <input> elements because we can have multiple text boxes to which the watermark needs to be applied. We also want to be able to pass on the ‘inputWatermark’ along to the next method in the chain. To do this, our plugin must return the ‘this’ keyword. So our shell code is modified to the following


(function ($) {
    $.fn.extend({
        inputWatermark: function () {
            var options = datasource;
            return this.each(function () {
                // plugin code
            });
        }
    });
})(jQuery);

Step 4: Setting up the Code
The logic for the watermark behavior is simple.
1. If no text have been provided by the user, show the watermark text
2. When user enters the input box, remove the watermark
3. When the user exits the input box if they haven’t added any text, put the watermark back.

To do the above, we handle the blur and focus events of the input element. On plugin initiation, we check if value provided is not empty, if it is, we add the watermark. The code is as follows


(function ($) {
    $.fn.extend({
        inputWatermark: function () {
            return this.each(function () {
                // retrieve the value of the ‘placeholder’ attribute
                var watermarkText = $(this).attr('placeholder');
                var $this = $(this);
                if ($this.val() === '') {
                    $this.val(watermarkText);
                    // give the watermark a translucent look
                    $this.css({ 'opacity': '0.65' });
                }



                $this.blur(function () {
                    if ($this.val() === '') {
                        // If the text is empty put the watermark
                        // back

                        $this.val(watermarkText);
                        // give the watermark a translucent look
                        $this.css({ 'opacity': '0.65' });
                    }
                });



                $this.focus(function () {
                    if ($this.val() === watermarkText) {
                        $this.val('');
                        $this.css({ 'opacity': '1.0' });
                    }
                });
            });
        }
    });

})(jQuery);

We update our HTML to the following


<!DOCTYPE html>
<html>
<head>

    <title>TextBox Water Marking</title>
    <script src="Scripts/jquery-1.7.2.js" type="text/javascript"></script>
    <script src="Scripts/input-watermark.js" type="text/javascript"></script>
</head>


<body>
    <input id="input1" placeholder="Placeholder here..." />
    <input id="input2" placeholder="2nd Placeholder" value="This is actual Text" />
    <script type="text/javascript">

        $(document).ready(function () {
            $(':input').inputWatermark();
        });

    </script>

</body>
</html>

As seen above we are assigning the plugin using the type selector. This assigns the plugin to all input boxes. The beauty is that we use HTML5 style markup and the same attribute (placeholder).

We could assign the plugin to individual input elements too by using the id selector

$('#input1').inputWatermark();
or
$('#input2').inputWatermark();

Finally our code in action looks as follows

ie9-watermark-fix


See a Live Demo




3 comments:

Unknown said...

This doesn't appear to be a graceful "Fallback" as you mention, but rather a complete override.

I would prefer only "fallback" on browsers which do not support the HTML5 placeholder attribute.

б5 said...

in step 3 there is var options = datasource; Is tat copy/paste "error" because it's not used?

Vinix said...

What would happen if you submit the form without entering anything in watermarked textbox? ;)