Friday, September 28, 2012

Custom Data Attribute "data-*"

I learned something today, that I wanted to share.

You see I had some elements on a web page that needed to make an AJAX call back to the server when you clicked on them.  But I needed some extra data to go along with that call that would be different for each element.  

The method I devised was to put that data in the id attribute like this:

<tr id="fileid-513-type-17" ... > ... </tr>

Now all I had to do was parse the id attribute in my script and make the AJAX call.  Not the prettiest way to get it done, but it works.

Well, today while reading Unobtrusive JavaScript by Jason Moon I found the following:
Each unobtrusive widget can be configured using HTML5 data- attributes on the element. The sole purpose of these attributes is to provide information to the JavaScript code.
That is exactly what I was looking for 6 months ago.  It makes reference to the W3C HTML5 Specification: 3.2.3.9 Embedding custom non-visible data with the data-* attributes.

Using the custom data attributes I could have done the following:

<tr data-fileid="513" data-type="17" ... >...</tr>

Now in my script I would use jQuery to parse out the data for me like so:

var id = $( event.target ).data( "fileid" );
var type = $( event.target ).data( "type" );

There is one little caveat with the naming convention.  All attributes of an HTML element get lowercased automatically.  This is true for custom data attributes as well, because, they are attributes.  When jQuery and other APIs load the data, they will camelcase the names of the attributes based on the hyphens in the attribute name.  Here is an example with jQuery:

<tr id="myTR" data-fileid="213" data-file-type="pdf" data-file-size="2143">

var fileid = $( "#myTR" ).data( "fileid" );
var fileType = $( "#myTR" ).data( "fileType" );
var fileSize = $( "#myTR" ).data( "fileSize" );

// or getting alls the values as a JavaScript object
var obj = $( "#myTR" ).data();

alert( "ID = " + obj.fileid + "\nFile Type = " + obj.fileType + "\nFile Size = " + obj.fileSize );

Notice how the hyphens are removed and we get a capital letter after each hyphen?

Here is an example using element.dataset:

var element = document.getElementById( "myTR" );

alert( "ID = " + element.dataset.fileid + "\nFile Type = " + element.dataset.fileType + "\nFile Size = " + element.dataset.fileSize );



Wow.  So much easier.  I hope that helps you out.  It sure helped me.

Now off to refactor some code.

No comments: