2

What I want to do is to set options into plugin like you normally would, but to also override those options with html5 data-attributes.

Here I have exactly that (jsfiddle), but there's a slight problem with that.

JSFiddle Code:

(function($){
    $.fn.extend({
        test: function(options) {

            var defaults = {
                background: null,
                height: null
            };

            var options = $.extend( defaults, options);

            return this.each(function() {
                  var o = options;
                  var obj = $(this);
                  var objD = obj.data();


                    // background
                    if ( !objD.background) {
                        var cBG = o.background;
                    }
                    else {
                        var cBG = objD.background;
                    }

                    // Opacity
                    if ( !objD.height) {
                        var cH = o.height;
                    }
                    else {
                        var cH = objD.height;
                    }

                    obj.css({
                        background: cBG,
                        height: cH  
                    });

            });
        }
    });
})(jQuery);

$(document).ready(function() {
    $('.test').test({

        background: 'red',
        height: 400

    });
});

The method that I'm using in the jsfiddle bloats the code so much, even with just 2 different options that are also using data.

Question is: How could I achieve same end result with less code, to determine wether or not data should be used?



Here is the part of the code from the jsfiddle, that determines wether or not to use data.

// objD is obj.data();

// background
if ( !objD.background) {
    var cBG = o.background;
}
else {
    var cBG = objD.background;
}

// Opacity
if ( !objD.height) {
    var cH = o.height;
}
else {
    var cH = objD.height;
}

obj.css({
    background: cBG,
    height: cH  
});

3 Answers 3

5

I had a feeling that there might be a better solution, but I wasn't able to get it working, until now.


Of course I am no expert, but this seems to work and shortens the code even more, since it works the same way the plugin options normally do, it just adds the data-attribute in there.

  1. Default - Initially use default options.
  2. Custom - If set, use custom options to override defaults.
  3. Data - If set, use data to override both.

http://jsfiddle.net/lollero/HvbdL/5/

o = $.extend(true, {}, options, $(this).data() );


Here's another jsfiddle example.

This one toggles the width of each box on click. The middle box has a data-attribute with bigger width value than the other divs.

As an extra example, here's the same thing with 1 more option added in to the mix.

Sign up to request clarification or add additional context in comments.

Comments

2

Well, one common trick is the double-pipe "or" operator in your assignment. If the first value is true, the second one is ignored, since only one true statement is enough to make the entire expression true:

var cBG = objD.background || o.background;
var cH = objD.height || o.height;

In fact, if you don't need those variables anywhere else, just add the results into the last statement:

obj.css({
    background: (objD.background || o.background),
    height: (objD.height || o.height)
});

Your fiddle

Simplified example

Now if objD.background is any "falsey" value (such as null, undefined, false, zero, or the empty string), then o.background will automatically be used. If for some reason you don't want that, you should use the ternary operator with an appropriate test instead:

obj.css({
    background: (objD.background!=undefined) ? objD.background : o.background,
    height: (objD.height!=undefined) ? objD.height : o.height
});

5 Comments

Simpler than what I did, but I'm a bit concerned how if I would set value 0 into data- it seems to jump straight to options. Same thing happens if data has false, it jumps straight to options. Which means that I can't override with those values.
if you set objD.background to zero, then !objD.background would have evaluated as true and you'd get the same result. But I'll update my answer to address that.
I see.. I used to use if ( objD.cBG != null ){ options } else { data } but thought that using ! was a bit shorter, so I jumped to that without thinking about it much :)
It's worth testing for different "falsey" values, too. For instance, in JavaScript, it seems null==undefined is true, but null===undefined is not. Be careful what you let through.
In my prior comment/if statement I meant to put data before options ..I seem to have gotten confused. As far as you answer goes, thanks for help.
0

An easy way would be using the jQuery HTML5data plugin from Mark Dalgleish. The pro side of this plugin is namespacing so your config will never clash with the config of some other plugin.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.