2 comments
Retweet

A simple jQuery input hint plug-in

A popular feature that can be found lot of web sites is the pre-population of form fields. When focusing on the input the default value is removed and when losing focus is replaced if the field value is left empty .

This tutorial will take you through the process of developing a simple jQuery input hint in an unobtrusive manner, allowing the form to function as expected when JavaScript is not enabled.

Step One

Before we start on the plug-in itself, we need some basic HTML defining our form.

<form method="get" action="">
	<input type="text" value="" title="Search..." name="s" id="s" />
	<input type="submit" value="Search" />
</form>

Step Two

The first stage of plug-in creation is setting up the basic plug-in structure. I tend to stick to the custom aliasing method as this will prevent conflicts with other libraries or frameworks and still allow us to make use of the “$” alias.

To achieve this, we execute an anonymous function, passing jQuery through and using “$” as the alias (although this could be any variable name), creating the fn and then enable chaining by looping through and returning each matched element.

(function($) {
	$.fn.inputHint = function() {
		return this.each(function() {
			//...
		});
	};
})(jQuery);

You can read more about plug-in authoring on the jQuery site.

Step Three

This plug-in is going to allow the default value to be defined by either passing it in as a set value or fetching the value from the title attribute of the input.

To achieve the first method we are going to use the extend method, allowing us to globally set and re-define the customisations such as the hint value to use.

Here we take the globally defined values from the $.fn.inputHint.settings object and over-ride them with any values passed in by the callerSettings object. (Although we are using a deep / recursive merge in the example, it’s not totally necessary for this plug-in in it’s current state.)

(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			//...
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);

Step Four

Now that we can define any custom options, let’s move on to actually doing something useful.

We need the ability to set the value of the input to the predefined value if the input is empty and clear the default value when the input receives focus.

Setting the default value if the input is empty:

$(this).blur(function() {
	$(this).val($(this).val() == '' ? settings.value : $(this).val());
});

Clearing the default value  on focus:

$(this).focus(function() {
	$(this).val($(this).val() == settings.value ? '' : $(this).val());
});

If we added these two events to our plug-in directly, it would look as follows:

(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			$(this).blur(function() {
				$(this).val($(this).val() == '' ? settings.value : $(this).val());
			});
			$(this).focus(function() {
				$(this).val($(this).val() == settings.value ? '' : $(this).val());
			});
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);

We should however make use the chaining ability to cut down the amount of code we need to write.

The following introduces a couple of additions to go alongside the chaining, including the triggering of the blur event that will fire when the page loads and set the default value if necessary.

Here we have also included the ability to take the default value from the title attribute instead of the settings array (see variable v).

$.fn.inputHint = function(callerSettings) {
	var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
	return this.each(function() {
		var n = $(this), v = settings.value || $(this).attr('title');
		n.focus(function() {
			n.val(n.val() == v ? '' : n.val());
		})
		.blur(function() {
			n.val(n.val() == '' ? v : n.val());
		})
		.blur();
	});
};

Using what has been written so far will provide us with a working version, but there are a few additions.

We should unset the default value when the form is submitted, as most back end scripts will be checking against an empty value. This can be achieved by checking the existence of a parent form and unsetting the default value on submission by triggering the focus event.

The second addition is the ability to add and remove a class name to the input,  so we can set a style when the default value is present and a class name is defined (see addClass and removeClass).

Step Five: The Completed Plug-in:

(function($) {
	$.fn.inputHint = function(callerSettings) {
		var settings = $.extend(true, {}, $.fn.inputHint.settings, callerSettings);
		return this.each(function() {
			var n = $(this), v = settings.value || $(this).attr('title'), f = $(this.form);
			n.focus(function() {
				n.val(n.val() == v ? '' : n.val())
					.removeClass(settings.className);
			})
			.blur(function() {
				n.val(n.val() == '' ? v : n.val())
					.addClass(settings.className);
			})
			.blur();
			if (f) {
				f.submit(function(e) {
					n.trigger('focus');
				});
			}
		});
	};
	$.fn.inputHint.settings = {
		value: false,
		className: false
	};
})(jQuery);

To make the whole effect work, add either of the following snippets to your page or script.
The first will attempt to use the title attribute as there are no custom settings.

$(function() {
	$('#s').inputHint();
});

The second specifies a defined hint value and a class to add to the input when the hint is visible, which are passed through in the settings object.

$(function() {
	$('#s').inputHint({
		value: "Search",
		className: 'faded'
	});
});

You should place the plug-in inside a file called jquery.inputHint.js and include this file in your page, this conforms to the jQuery plug-in author guidelines (“Name your file jquery.[insert name of plugin].js”).

Additional Notes

This is just one method of achieving an input hint, an alternative method would be to use the the label tag instead of input and set the hint value based on this, or even place the label tag itself on top of the input.

This post was written by

2 comments

  1. Reply
    richie says:

    thanx, very helpful

  2. Reply
    Mkk says:

    Can we use image instead of hint text?

Have your say: