$.data() and Default Values

Jan24
Missing Image
By SiteCrafting Staff

Before the days of jQuery and HTML5, many tasks required raw JavaScript to implement. One of the most common was giving a text input box a default value. This is a useful design technique to label an input without taking up extra space. When it is done correctly it can give a clean feel and flow to your forms.



Here's how we used to accomplish this task with a search bar.

<input id="search" type="text" value="Search..." onfocus="setDefault(this)" onblur="swapDefault(this)"/>
function setDefault(elem) {
    if(elem.defaultValue === undefined) {
        elem.defaultValue = elem.value;
    }
    elem.value = '';
}

function swapDefault(elem) {
    if(elem.value.length === 0) {
        elem.value = elem.defaultValue;
    }
}

jQuery 1.3 added a useful function called .data() that saves data along with elements using an internal data store. This helps prevent memory leaks when the element is removed, and cleans up the code. It was quite useful for storing state data, related jQuery elements, or information about context. Below is an example of a text input box that saved the default state in the .data() function for our search bar.

<input id="search" type="text" value="Search..."/>
$('#search')
    .bind('focus', function () {
        if($(this).data('default') === undefined) {
            $(this).data('default', $(this).val());
        }
        $(this).val('');
    })
    .bind('blur', function () {
        if($(this).val().length === 0) {
            $(this).val($(this).data('default');
        }
    });

As you can see, it's pretty simple and we've used similar code here at SiteCrafting for a long time now. While this is very useful, it still has a few issues. Let's say you want to pre-populate the text input bar with something other then the default. This happens regularly in a search bar. What would you do?

Well, some super smart people at jQuery noticed that HTML5 has a attribute called data-* (which reads like data-anything or data-star). So they decided to add an extra check if nothing is in the jQuery .data() function. Now, as of jQuery 1.4, that function will also check the data-* attribute when there is nothing cached. So how does this change our code?

<input id="search" type="text" value="Search..." data-default="Search..."/>
$('#search')
    .bind('focus', function () {
        if($(this).data('default') === undefined) {
            $(this).data('default', $(this).val());
        }
        $(this).val('');
    })
    .bind('blur', function () {
        if($(this).val().length === 0) {
            $(this).val($(this).data('default');
        }
    });

This change frees up the value attribute to display what ever the last search query was. Now that the default state is just an attribute we can abstract this code a little more. Below, it is part of a live event. You can put this code anywhere during your page load and all inputs with a data-default attribute will get this function.

<input id="search" type="text" value="Search..." data-default="Search..."/>
$('input:text[data-default]')
    .live('focus', function () {
        if($(this).data('default') === undefined) {
            $(this).data('default', $(this).val());
        }
        $(this).val('');
    })
    .live('blur', function () {
        if($(this).val().length === 0) {
            $(this).val($(this).data('default');
        }
    });

There are many, many more uses for the .data() function. In the office, we have found it to be incredible for storing state data for shopping carts, drop down lists, and many other situations. It is also a nice alternative to running an Ajax call as the data will be stored locally and therefore might be a faster alternative. Best of all, it uses type inference to return more the just strings.

<input id="search" type="text" value="Search..." data-must-have-chars="3" data-must-be-email="false" data-some-obj="{foo: 'bar'}"/>
$('#search').data('must-have-chars'); // 3.0
$('#search').data('must-be-email'); // false
$('#search').data('some-obj').foo // "bar"

As for browser compatibility, this code works in every browser supported by jQuery. That includes IE6+, FF2+, Safari 3+, and Chrome 4+.

Another point, HTML5 has defined an attribute specifically for default values. It's called defaultValue, and you can read about it over at WHATWG. It's worth mentioning, but since very few browsers have implemented it, jQuery might be your best option... for now.


Dev

Back To Feed