My readers are probably sick and tired of me gushing over data attributes, and for that, I apologize. I'm just a huge fan of practical, useful solutions, and no, I'm not going to use this as opportunity to complain about how silly Canvas is again. Rather, I thought I'd whip up another simple example of how you can make use of data attributes in your shiny Ajax-enabled web sites.

If you don't remember what data attributes are, here's a quick reminder. Data attributes are a way to add ad hoc data to your DOM. By prefixing an attribute with data- in front of your name/value pair, your have HTML that is still valid no matter what name you use. So for example:

<img src="something" data-nsfw="true">

There is no data-nsfw attribute for the image tag, but because I began the attribute with data-, it's valid. Another example:

<img src="something" data-nsfw="true" data-hires="someurl">

In both examples, the browser blissfully ignores the custom attributes, but you can write your own code to do whatever you want with it. This comes in handy in numerous situations, but here's one simple example. Imagine I'm selecting data from a table that includes price information. To make it pretty, I'll wrap the output of the price in a function to render it as a currency. Here's an example in ColdFusion:

Price: #dollarFormat(price)#<br/>

For the hell of it, here's the PHP version of it:

echo money_format('%i', $price) . "\n";

This outputs something like : $12,3900.11. What if you wanted to work with this price in JavaScript but treat it as a number? You would need to strip out the currency, possibly even the commas first. Instead of worrying about that, what if we used data attributes to store the "naked" price as a simple number? This will be hidden from the end user (technically not hidden - it will be available in view source) but will be available for our code. Here's an example. The code below loops over a query of art work. (I'll show the entire template in a bit.)

<cfoutput query="getArt"> <div class="artPiece" data-id="#artid#" data-price="#price#">

<h2>#artname#</h2> Price: #dollarFormat(price)#<br/> Media: #mediatype#<br/> Artist: #firstname# #lastname#<br/> #description#<br/> <img src="/cfdocs/images/artgallery/#largeimage#"> </div> </cfoutput>

As you can see, I've included two data attributes in my div tag. One of the primary key of the record and one for the price. To be clear, I could have used other methods. I could have used a hidden form field for example. But this is much cleaner. Grabbing the values is a matter of simple JavaScript, but jQuery makes it even easier. Here's the complete template:

<!--- get art work ---> <cfquery name="getArt" datasource="cfartgallery"> select art.artid, art.artname, art.description, art.price, art.largeimage, artists.firstname, artists.lastname, media.mediatype from art join artists on art.artistid = artists.artistid join media on art.mediaid = media.mediaid </cfquery>

<html>

<head> <title>Data Example</title> <link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.3.0/bootstrap.min.css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<style> .artPiece { margin: 12px; border-style:solid;
border-width:thin; width: 230px;
padding: 5px; float: left; }

</style> <script type="text/javascript"> $(function() { $(".artPiece").click(function() { var selectedId = $(this).data("id"); var selectedPrice = $(this).data("price"); console.log(selectedId+" "+selectedPrice); }); }); </script> </head>

<body>

<div class="container">

<h1>Art Work</h1>

<cfoutput query="getArt"> <div class="artPiece" data-id="#artid#" data-price="#price#">

<h2>#artname#</h2> Price: #dollarFormat(price)#<br/> Media: #mediatype#<br/> Artist: #firstname# #lastname#<br/> #description#<br/> <img src="/cfdocs/images/artgallery/#largeimage#"> </div> </cfoutput>

</div>

</body>

</html>

You can ignore the SQL and most of the formatting. Focus on the fact that I've got a click handler on my div. Grabbing my two values is as simple as using jQuery's data method. You can demo this below.