HTML5 Data attributes and jQuery’s .data – pairing made in heaven
May 12, 2010 in jQuery Plugins
UPDATE
jQuery 1.4.3+ now does this in core.
No need for this plugin!
I really like the idea of the data-* properties in the spec for HTML5, unfortunately they’re not supported directly by any browser it seems yet; even jQuery 1.4.2 doesn’t really support them (due to the non-browser support I guess).
Anyway, I really wanted to make use of them in an application I’ve been using and after reading John Resig’s (@jresig) post on the subject (http://ejohn.org/blog/html-5-data-attributes/) I set about adding a little snippet to extend jQuery’s .data so that it would support these parameters. So here is the small plugin that will extend the data function in jQuery to enable access to this functionality.
Enjoy
(function($){
$.fn.extend({
'_data': $.fn.data,
'data' : function( key, value ) {
if ( typeof key === "undefined" && this.length ) {
return jQuery.data( this[0] );
} else if ( typeof key === "object" ) {
return this.each(function() {
jQuery.data( this, key );
});
}
var retValue;
retValue = $.fn._data(key, value);
if ('undefined' == (typeof retValue) || retValue.length == 0) {
var nakedElem = this.get(0);
if (nakedElem.hasOwnProperty('dataset')) {
if ('undefined' != (typeof nakedElem.dataset[key])) {
retValue = nakedElem.dataset[key];
}
} else {
retValue = this.attr('data-'+key);
}
}
return retValue;
}
});
})(jQuery);
All comments are gratefully received
Wonderful! I’ve wanted the same thing, thank you for coding it up.
you’re welcome
Can I just use the standard .attr? Or do data-* attributes not show up there?
you can do the standard .attr as i have done in my little plugin. Just use .attr(‘data-’+name)
Hehe, OK I still don’t get it!
What I’d LOVE to do is $(‘#obj’).data.img to load the ‘data-img’ attribute. Failing that, $(‘#obj’).data(‘img’). Which isn’t really that much better than $(‘#obj’).attr(‘data-img’), which is built-in…
Couldn’t .data() return an object, which would at least let us do $(‘#obj’).data().img. Which at least saves us from quoting it.
What’s the ‘dataset’ stuff in this code do/for?
$(‘#obj’).data(‘img’);
This plugin maps the data-img to that.. as an extension to the jQuery data storage in core.
sorry didn’t see the full comment. basically the dataset stuff is a html5 preview type thing. At the moment it seems that none support it. When they do the data will be in that array, which will be available through basic dom eg domElement.dataset['key'] would be able to access
I can see what you mean about the .data.img but then again the underlying calls to enable that would be completely messy without full browser support backing it up, after all if something changes, 1 gets removed, another added.. where do you get the info that it has happened, there are no “data has changed” events.
So, unfortunately, there is no way around the issue other than what is done.
Well, it seems that jQuery 1.4.3 addresses HTML5 data-attributes directly now: http://api.jquery.com/data/
hi i was working with the .attr() api , it works good with most of the element but,
as far as forms are concerned i cannot change the onsubmit attribute
if onsubmit = empty it updates the attribute but
if onsubmit =”xyz();” it does not updates the attribute
is this a bug or am i doing some thing wrong
my code is
$(‘div.ProceedToCheckout form’).each(
function(i){existingOnSubmit=$(this).attr(‘onsubmit’);
if (typeof existingOnSubmit==”undefined”){existingOnSubmit=”;}
newOnSubmit=’return PreventExternalCheckout.showTimeOutDialog(); ‘+existingOnSubmit;
$(this).attr(‘onsubmit’,newOnSubmit);
console.log($(this));
}
);
Hey Sven,
It sure does. They included it. This was made before 1.4.3
thanks for you reply i was working on version 1.3.2 switching to the latest version will help i guess.
Hi Samir,
thanks for your comment (even if it is outside the remit of this posting);
The issues is that you can’t set the “onsubmit” and have it work as an event via the attr ability. This is because the event gets parsed to an actual event on dom load/parse.
You need to bind the event to the form after the fact.
Another issue i see with your code is that you are not using local variables and as such variables like existingOnSubmit and newOnSubmit as bleeding through to the global scope.
Further to this, you are calling jquery a few too many times, you really should store in a variable. I’ve taken the liberty of using the code from http://joshuaclayton.github.com/code/2009/06/08/handling-jquery-and-onsubmit.html to improve yours as well as fixing the issues outlined above
$(‘div.ProceedToCheckout form’).each(function(i){
var thisForm = $(this),
existingOnSubmit=thisForm.attr(‘onsubmit’);
if (typeof existingOnSubmit != ”undefined”){
existingOnSubmit = new Function(existingOnSubmit);
} else {
existingOnSubmit = function() {}; // empty fn to prevent error
}
thisForm.submit(function() { existingOnSubmit(); return PreventExternalCheckout.showTimeOutDialog(); });
});
thanks once again