Search code examples
jquerypluginsextend

jQuery extend() in extend()


These are my jQuery plugin parameters so far:

function lightbox( options )
{
 // setting default parameters
 var params = $.extend(
 {

    // show/hide & enable/disable options
    keyNav : true,                      // boolean
    objClickNav: false,                 // boolean
    showNav : true,                     // boolean
    showTitle : true,                   // boolean
    showPagination : true,              // boolean
    debugMode : false,                  // boolean
    disableScrolling : true,            // boolean
    fullscreen : false,                 // boolean

    autoScale : true,                   // boolean
    staticHeight: 'auto',               // integer or 'auto'
    staticWidth: 'auto',                // integer or 'auto'

    // content options
    contentType : 'image',              // defines the type of content shown in the lightbox
                                        // options: 'image'
    animationType : 'default',          // defines the type of animation when switching objects
                                        // options: 'default', 'slide'

 }, options);
}

I couldn't find an answer anywhere on the internet, so that's why I'm asking it here. I want to have an extend() inside the current extend(), so I can declare my plugin like this:

lightbox({
  keyNav : true,
  showNav : false,
  scale({
    autoScale : false,
    staticHeight : 800,
  })
  content({
    contentType : 'image',
    animationType : 'slide',
  })
});

What is the correct way of doing this?


Solution

  • $.extend documents a deep flag. scale and context would typically be objects, which the deep flag would tell extend to clone.

    Also note that the first entry should be the object to extend, which you normally wouldn't want to be your defaults object. (Although in your case, you're recreating the defaults each time, so that's fine.)

    So:

    var params = $.extend(
        true, // <=== The `deep` flag
        {},   // <=== The new object that will be stored in `params`
        {/*...your big defaults object...*/},
        options
    );
    

    Simple example:

    (function($) {
      var fooDefaults = {
        text: "coolness",
        style: {
          color: "green",
          fontWeight: "bold"
        }
      };
      
      $.fn.foo = function(options) {
        var params = $.extend(true, {}, fooDefaults, options);
        this.data("params", params); // Just so we can look at them
        return this.each(function() {
          $(this).text(params.text).css(params.style);
        });
      };
      
    })(jQuery);
    
    var a = $("#a");
    var b = $("#b");
    a.foo({text: "I'm a"});
    b.foo({style: {color: "blue"}});
    console.log("a's text: " + a.data("params").text);
    console.log("a's color: " + a.data("params").style.color);
    console.log("b's text: " + b.data("params").text);
    console.log("b's color: " + b.data("params").style.color);
    <div id="a"></div>
    <div id="b"></div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>