Projects
  Site > Home > Projects > jQuery > defineDatasets   
jQuery Plug-in "defineDatasets"

Overview

This plug-in is intended to be used with HTML 5 "custom attributes", which begin "data-". It does NOT use attrNameBegins, my custom selector for attribute name prefixes, for 2 reasons:

  1. So that they can be independent of one another. (That is, so that you don't have to code 2 script tags just to use this 1 plug-in.)
  2. Using this plug-in alone is somewhat faster, because it doesn't have to make 2 passes through the attributes array for each element of the wrapped set.

However, if you WANT to use attrNameBegins to namespace your custom attributes, it doesn't hurt to include both and use both.

Usage

First, define a jQuery object that selects all DOM objects for which you might have defined a data-* attribute. (Although you could, there's not much sense in looping over all DOM elements with $("*"), for example, if you're only planning on defining data-* attributes for a much smaller subset, such as $("button,input,select,textarea"), right?) Then, just chain this method onto the jQuery object to define the JavaScript "dataset" object for all DOM elements in the jQuery object, regardless of whether or not they actually have data-* attributes (per the HTML 5 Draft Specification). Finally, this method leaves the contents of the jQuery object the same for further chaining.

As specified by the HTML 5 Draft Specification, the property name in the dataset object is the same as the attribute name, but stripped of "data-" and converted to lower case. So the attribute data-mixedCaseExample is used to initialize the contents of this.dataset.mixedcaseexample. The value of the attribute is not altered. That is, the dataset property gets whatever was returned by getAttribute().

Also per the HTML 5 Draft Specification, dataset is saved off as a property of the DOM object. jQuery plug-in best practices usually call for data to be saved off with ".data()", not as a property of the DOM object itself. But to do so in this case would be to force you to code differently from the HTML 5 spec. The whole idea of this plug-in is to give you the capabilities of the HTML 5 spec in advance of browser implementation. It would totally defeat this purpose to use ".data()".

Examples

Suppose that you're using data-* attributes only on <input type="text"> elements. This would be an example usage:

    <script src="jquery.js"></script>
    <script src="jquery.defineDatasets.js"></script>
    <script>

    $(document).ready(function()
        {
        $("input[type=text]").defineDatasets();
        });

    </script>

Presumably, once browsers start supporting custom attributes, you would probably prefer to use the one defined by the browser. But if you would prefer the dataset that this plug-in defines to the one defined by a browser, you can pass an option to do so:

    <script src="jquery.js"></script>
    <script src="jquery.defineDatasets.js"></script>
    <script>

    $(document).ready(function()
        {
        $("input[type=text]").defineDatasets({overwriteExistingDatasets:true});
        });

    </script>

Another situation in which you might want to use "{overwriteExistingDatasets:true}" is after externally modifying a data-* attribute:

    <input type="button" value="Use DD-MM-YYYY Format" ... onclick="
    this.form.BirthDate.setAttribute('data-monthAndDayOrder','British');
    $(this.form.BirthDate).defineDatasets({overwriteExistingDatasets:true});
    ">

But of course, it would be faster and easier just to modify the dataset directly, if you know for-sure that it exists:

    <input type="button" value="Use DD-MM-YYYY Format" ... onclick="
    this.form.BirthDate.dataset.monthanddayorder = 'British';
    ">

Testing

Of primary concern is whether the references to pObj.attributes and pObj.attributes[i].nodeName are proper DOM references for the browser at hand. I have tested that defineDatasets works correctly with the following browsers (note the absence of Windows MSIE 6):

  • Mac:
    • Firefox 3.5.6
    • Netscape 7.2
    • Opera 9.25
    • Safari 4.0.4
  • Windows:
    • Firefox 3.5.6
    • Google Chrome 3
    • MSIE 7
    • Netscape 7.1
    • Netscape 8.1
    • Opera 10.10
    • Safari 4.0.4

I tried to test attrNameBegins, which contains similar code, using MSIE 6, but Windows Update upgraded me to MSIE 7 without even asking for my permission to do so. I sat through what seemed like HOURS of Windows Updates (because I don't use my Windows machine much), only to not have MSIE 6 anymore at the end of the process. Very frustrating. Very frustrating indeed. Especially when you consider that MSIE 6 is the browser most likely to have a DOM incompatible with this plug-in.

That said, you can do your own testing with the following hotlinks:

View Source

The following hotlinks pop up a new window containing the source code. Then you can do a File > Save As ... to save the source to your hard drive, if you like.

If you'd prefer to get these plugins from the plugins.jquery.com site, so that you can see and verify their MD5 hashes, for example, the following hotlinks pop up a new window containing the plugins.jquery.com URLs:

Future Plans

Ian Hickson is one of the two authors of the HTML 5 Draft Specification. He recently confirmed to me that, in HTML 5, dataset is intended to be a live connection between the dataset properties and their associated data-* attributes. That is, setting:

this.dataset.myvar = 'value';

results in:

this.setAttribute('data-myvar','value');

So there's an enhancement already in the works to define getters and setters that establish this live connection, in case there are those who have a real need for it. The option name has already been specified: "connectToAttributes".

Complicating this enhancement is MSIE 8's limited implementation of getters and setters and the fact that earlier MSIEs don't implement getters and setters at all. For this reason, connectToAttributes would initially be implement only for (Mac and PC):

  • Firefox 2.0+
  • Google Chrome 1.0+
  • Opera 9.5+
  • Safari 3.0+

Not supporting MSIE goes against the cross-browser philosophy of jQuery, which is clearly problematic. But unless you actually intend to reference the data-* attributes after changing the value of associated dataset properties, it doesn't matter. You can simply code to the dataset object and ignore the data-* attributes thereafter.

So although a live connection to data-* attributes is necessary for a browser to be said to have implemented HTML 5, I'm not altogether convinced that connectToAttributes is a critical feature for this plug-in's users. That's why I didn't delay the initial release of the plug-in for this feature.