Skip to main content Accessibility Feedback

Setting multiple JavaScript plugin options with a single data attribute

Update: After a chat with Todd Motto, I’ve updated my approach.

All of my native JS plugins let users pass in options during initialization. For some (like Smooth Scroll and Jellyfish), I also provide a way for developers to override these options an item-by-item basis using data attributes.

Developers simply pass in all of their overrides via a single data-options attribute rather than forcing developers to use a data attribute for every option they want to change. Foundation uses this approach in several of their scripts.

// This
data-options="speed: 500; 
              easing: easeInOutCubic; 
              offset: 0; 
              updateURL: false"; 

// Instead of this
data-speed="500" 
data-easing="easeInOutCubic" 
data-offset="0" 
data-updateURL="false" 

To do this, I wrote a simple helper function that converts the contents of the data-options attribute into an object.

data-options.js #

/**
 * Convert data-options attribute into an object of key/value pairs
 * @private
 * @param {String} options Item-specific options as a data attribute string
 * @returns {Object}
 */
var getDataOptions = function ( options ) {
    var settings = {};

    // Trim whitespace from a string
    var trim = function ( string ) {
        return string.replace(/^s+|s+$/g, '');
    };

    // Create a key/value pair for each setting
    if ( options ) {
        options = options.split(';');
        options.forEach( function(option) {
            option = trim(option);
            if ( option !== '' ) {
                option = option.split(':');
                settings[option[0]] = trim(option[1]);
            }
        });
    }

    return settings;
};

Example #

Markup

<a 
class="example" 
href="#" 
data-options="speed: 500;
              easing: easeInOutCubic;
              offset: 0;
              updateURL: false"; 
>
    link
</a>

JavaScript

var item = document.querySelector('.example');
var options = getDataOptions( item ? item.getAttribute('data-options') : null );

console.log(options);
// Returns: Object{speed: 500, easing: easeInOutCubic, offset: 0, updateURL: false}

See it in action in Smooth Scroll.

Update #

Todd Motto pointed out the dangers of using this approach:

data-json

All values, even numbers and booleans, are converted to strings. His solution is to use real JSON in your markup:

Markup

<a class="example" href="#" data-options='{
    "speed": 500,
    "easing": "easeIn OutCubic",
    "offset": 0,
    "updateURL": false
}'>link</a>

JavaScript

var getDataOptions = function ( options ) {
    return (!options || typeof JSON.parse !== 'function') ? {} : JSON.parse(options);
};

var item = document.querySelector('.example');
var options = getDataOptions( item ? item.getAttribute('data-options') : null );

console.log(options);

I’ll be updating my scripts accordingly.


🚀 Make 2018 the year you master JavaScript! My pocket guides and mini courses are short, focused, and made for beginners. You can do this!

Have any questions or comments about this post? Email me at chris@gomakethings.com or contact me on Twitter at @ChrisFerdinandi.

Get Daily Developer Tips