Using jQuery to leverage HTML5 data attributes

Using jQuery to leverage HTML5 data attributes

The tech behind the Internet evolves pretty quickly these days and HTML5 is the latest acronym you should have in your toolbox. I keep it right next to the latest trusty version of jQuery, my favorite “do more, write less” JavaScript library.

Some folks have a hard time seeing how the two complement each other. Sometimes it seems like HTML5 was designed to make tools like jQuery unnecessary. Not so, courageous reader! Let me show how HTML5 gives jQuery a whole new layer of awesome.

So how does it work?

HTML5 allows us to create our own custom attributes to store data. Custom attributes can be called anything we like, like variable names, but they need to be prepended with the word ‘data’, and words are separated by dashes. You could add “foo”, “bar”, and “foo bar” data attributes to a paragraph like this:

[code lang=”html”]
<p id="para" data-foo="bar" data-bar="baz" data-foo-bar="true">
This is dummy text, dummy.
</p>
[/code]

With just JavaScript to fetch the values, use either the getAttribute() method or the dataset property, which inflects dashed-names into camelCase:

[code lang=”javascript”]
<script type="text/javascript">
var para = document.getElementByID(‘para’);

console.log(para.getAttribute(‘data-foo’));
// Expect string "bar"

console.log(para.dataset.bar);
// Grabs "data-bar"
// Expect string "baz"

console.log(para.dataset.fooBar);
// Grabs "data-foo-bar" ↑↑↑↑↑↑ Here be magic!
// Expect string "true"
</script>
[/code]

jQuery’s data() method allows us to store and retrieve arbitrary data about an element in a memory-efficient manner. Like getAttribute(), jQuery’s data() method can read HTML5 data attributes, but it also does something that getAttribute() doesn’t:

[code lang=”html”]
<section data-role="page" data-page-num="42" data-hidden="true">
<!– Imagine a bunch of page-type content here… –>
</section>
[/code]

 

[code lang=”javascript”]
<script type="text/javascript">
console.log($(‘section’).data(‘role’));
// Expect string "page"

console.log($(‘section’).data(‘pageNum’);
// Expect 42, an integer…! ↑↑↑↑↑↑↑↑ Here be magic!

console.log($(‘section’).data(‘hidden’);
// Expect the boolean TRUE!
</script>
[/code]

Yes, our good friend jQuery inflects the name of the data attribute – a la dataset – and converts the value into the appropriate type. This even works for more complex types, like arrays and objects:

[code language=”html”]
<a href="#datepicker" data-options="{‘hidden’: true}">
<em>March 15, 2012</em>
<span data-icons="[‘calendar’, ‘arrow-dn’]"></span>
</a>
[/code]

 

[code language=”javascript”]
<script type="text/javascript">
console.log($(‘a’).data(‘options’));
// Expect {‘hidden’: true}

console.log($(‘a > span’).data(‘icons’));
// Expect [‘calendar’, ‘arrow-dn’];
</script>
[/code]

A Tale of Two Drop-downs: A Real-World Example

On my last freelancing assignment, I was working for a company whose primary business was staffing and recruiting. I was leading the development to replace their current business software with something shiny and new, and what could be shinier or newer than HTML5?

It wasn’t long before we ran into one of those “problem areas” that all the in-house folks had struggled with. They were using two standard select elements to produce drop-down menus for selecting personnel and positions. Those select elements were probably sufficient two or three years ago when the application was first built and the drop-downs had fewer options, but several thousand active personnel and positions later…

We decided to replace those horribly dysfunctional drop-downs with autocomplete widgets courtesy of jQuery UI. That way, the users pick from a much shorter list by typing a person’s name or employee number. We wired up some routes for personnel and positions that would accept a search term and return matching results as JSON. After that, we just had to add the widgets:

[code lang=”html”]
<dl>
<dt><label for="personnel_id">Personnel</label></dt>
<dd>
<input type="text" name="personnel_id"
id="personnel_id" class="autocomplete" />
</dd>
<dt><label for="position_id">Position</label></dt>
<dd>
<input type="text" name="position_id"
id="position_id" class="autocomplete" />
</dd>
</dl>
[/code]

 

[code lang=”javascript”]
<script type="text/javascript">
(function($){ // closure
$(function(){
/**
* First, store the appropriate "source" url
* on each element with data() for use below.
*/
$(‘input#personnel_id’).data(
‘autocompleteSource’, ‘/personnel.json’
);

$(‘input#position_id’).data(
‘autocompleteSource’, ‘/positions.json’
);

/**
* Using each() allows us access to the <input>
* element as "this", which we need below…
*/
$(‘input.autocomplete’).each(function(){
/**
* The initialization for each element is
* basically identical, except for the
* "source" option, which we’ll fetch from
* the element with the data() method.
*/
$(this).autocomplete({
source:$(this).data(‘autocompleteSource’)
});
}); // END each
}); // END document.ready
})(jQuery); // END closure
</script>
[/code]

Let’s Make Better Mistakes Tomorrow

Well, that looks good enough. It certainly works, but I’m one of those compulsive, perfectionist Agilistas who Refactor Mercilessly. Instead of tacking the source URLs on with jQuery, why not put them on the element directly? Without changing the Javascript, we can just throw some data attributes onto the input elements:

[code lang=”html”]
<dl>
<dt><label for="personnel_id">Personnel</label></dt>
<dd>
<input type="text" name="personnel_id"
id="personnel_id" class="autocomplete"
data-autocomplete-source="/personnel.json" />
</dd>

<dt><label for="position_id">Position</label></dt>
<dd>
<input type="text" name="position_id"
id="position_id" class="autocomplete"
data-autocomplete-source="/positions.json" />
</dd>
</dl>
[/code]

Finishing Touches

Since jQuery will happily convert those complex data types for us, we can get away with even more magic. The autocomplete widget is expecting an object packed with options, so let’s give it one:

[code lang=”html”]
<!– This is just an abbreviated example… –>
<input type="text" name="personnel_id"
id="personnel_id" class="autocomplete"
data-autocomplete-options="{‘source’:’/personnel.json’,’delay’:1000}" />
[/code]

 

[code lang=”javascript”]
<script type="text/javascript">
(function($){ // closure
$(function(){ // document.ready
$(‘input.autocomplete’).each(function(){
/**
* Initialize the autocomplete widget
* with the options from the element,
* defaulting to an empty object if
* the data attribute isn’t set.
*/
$(this).autocomplete($(this).data(
‘autocompleteOptions’
) || { });
}); // END each
}); // END document.ready
)(jQuery); // END closure
</script>
[/code]

Well, it’s not really magic; it’s just good technique. Just keep in mind that without HTML5 data attributes, all this convenience wouldn’t be possible and we’d have to resort to our sloppier first pass or use an HTML5 shim.

What have we learned?

There are a ton of new features baked into the HTML5 spec and current browser technology, but that doesn’t render our “oldies but goodies” – like jQuery – useless. If anything, jQuery has become even more useful with the addition of all those new tricks. Using jQuery to leverage HTML5 data attributes, you can “do more, write less” and keep your code nicely organized and clean.

9 Comments

  1. kaidez

    Also, jQuery Mobile is veeeeeery big on data attributes.

    Reply
  2. Lenny

    Very cool. I did not know .data() would autoconvert types, that’ll be super handy.

    Putting the source and options into the HTML element seems neat, but I’ve been using classes for my autocomplete widgets, so they are more easily reusable. The web app I’m working on uses the same autocomplete box (with the same source and visual effects) in many places, so copying the options into each of those elements would be a bit of a maintenance headache. But a cool technique, nonetheless!

    It also may be worth pointing out that while data attributes are in the HTML5 spec, from what I’ve seen so far they will still work in older browsers. Though they won’t validate, getAttribute() will still be able to retrieve them.

    Reply
  3. JD

    Quick note. Under “Finishing Touches”, the jQuery IIFE (Immediately Invoked Function Expression) is not closed properly. Minor over site, but could screw up a newbie. Should be…

    (function( $ ) {
    // Do your awesome jQuery stuff here
    })( jQuery );

    Reply
    • David Rogers

      Thanks, @JD, and good catch. I’ll get with the UMS guys to update the code sample in the article.

      Reply
  4. Jackson Stephens

    Hopefully this helps someone, but the following would be interpreted by jQuery as a string, not an array:

    data-icons=”[‘calendar’, ‘arrow-dn’]”

    Which has been driving me crazy. I found that if you reverse the orders of the quotation marks or use eval(), jQuery will recognize that as an array.

    Reply
    • Kodeart

      The valid JSON syntax is,
      – whole attribute value is in single quotes
      – key/value data pair(s), or array elements are in double quotes

      Easy to make a mistake.

      Reply
  5. Waseem

    Thanks for this nice introduction.

    Reply
  6. Majid Lotfi

    Hi,
    I just started learning html5 and jquery, Thank you for this tutorial, I will appreciated if you can post or send me the source code for this example with sample json.
    Thanks

    Reply
  7. GeLiGeLu

    This is a very useful function. You should be aware that when you use .data() to add data to a node, that it doesn’t change the DOM, so if there is a function or piece of code elsewhere relying on the attribute, don’t expect it to be available if you’re adding it dynamically using jquery.

    Reply

Trackbacks/Pingbacks

  1. Tweet-Parade (no.24 June 2012) | gonzoblog.nl - [...] Using jQuery to leverage HTML5 data attributes - HTML5 allows us to create our own custom attributes to store data. Custom…
  2. The Weekly Web Design Update – Articles, Resources, Tutorials and Inspiration [#003] | Oirs World - Design News and Ideas - [...] Using jQuery to leverage HTML5 data attributes [...]
  3. MVC 4 – Using HTML5 “data-” attributes with Jquery | a developer's notes - a semi-technical web development BLOG - [...] https://unmatchedstyle.com/news/html5-data-attributes-jquery.php Share this:TwitterFacebookLike this:Like Loading... [...]
  4. Polyclecta-blog - [...] Good write-up. Has proved to be very a handy technique for me…. Using jQuery to leverage HTML5 data attributes…

Submit a Comment

Your email address will not be published. Required fields are marked *

More News & Articles

The Essential Guide to Getting Started on Freelance Writing

The Essential Guide to Getting Started on Freelance Writing

Explore the lucrative and fulfilling world of freelance writing with our essential guide. Learn about specialties like blogging, social media, article, and technical writing. Build a portfolio, find work, set up your business, and discover the potential earnings. Embrace the freedom of working from home and follow tips for success in your dream career.

Securing Your Website: A DevOps Security Checklist

Securing Your Website: A DevOps Security Checklist

Learn how to secure your website with a comprehensive DevOps checklist. Dive into SSL/TLS encryption, password practices, and more. Discover the power of Content Security Policy and safeguard your online presence effectively.

EMAIL NEWSLETTER