views:

88

answers:

2

Hi jQuery ninjas.

I need your help. I have made a really clean and simple example to illustrate my problem. I have build my own jquery plugin:

(function($) {
  $.fn.setColorTest = function(options) {
    options = $.extend($.fn.setColorTest.defaults,options);
    return this.each(function() {
      $(this).css({ 'color': options.color});
    });
  }
  $.fn.setColorTest.defaults = {
    color: '#000'
  };
})(jQuery);

As you can see I'm setting a default color and making it possible for the user to change it. My problem/question is: I have two paragraphs on the same page where I want to use the default color for the first and a different color for the second paragraph:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title>Color Test</title>
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
 <script type="text/javascript">
      $(document).ready(function() {
         $('a#click').click(function() {
            $('#test1').setColorTest(); 
         });  
         $('a#click2').click(function() {
            $('#test2').setColorTest({color: '#fff666'});
         }); 
      });
    </script>
</head>
<body>
    <a id="click">click here</a>
    <a id="click2">click here2</a>
    <p id="test1">Test 1</p>
    <p id="test2">Test 2</p>    
</body>
</html>

My problem is that if I click on the second paragraph (p) that overrides the default color and afterwards clicks on the first p it will use the overwritten color and not the default color for the first p. How can I ensure that the first p always will use the default color? I know I can just define the color for the first p as well but that is not an option here

$('#test1').setColorTest('color': '#000');

So what to do?

A: 

Try:

options = $.extend({},$.fn.setColorTest.defaults,options||{});

I think what is happening is you are merging directly into your defaults as opposed to making a copy. By supplying an empty obj as the first arg for extend we make a copy for sure.

prodigitalson
A: 

I think this is what you're after (you need to change around your $.extend call slightly, it's currently setting properties on your .default object):

(function($) {
  $.fn.setColorTest = function(options) {
      options = $.extend({ color: '#000' }, options);
    return this.each(function() {
      $(this).css({ 'color': options.color});
    });
  }
})(jQuery);

You can see a demo here

You have to remember how $.extend() works, the format is $.extend(target, objectN), your current target is $.fn.setColorTest.defaults, which means it's getting overwritten, you need to either have an object per instance like I have above or copy your options before, so the core defaults aren't overwritten.

Here's a quick modified explanation demo showing the output

Nick Craver
It makes perfectly sense. Thanks for getting me on the right track Nick.
Bruno