3

How can I pass the default options from one method to the subsequence methods?

For instance, I have some default setting in the init method. and I want to use these settings for other methods such as show,

(function($) {
    var methods = {
        init: function(options) {
            var defaults = {
                element:    "selection"
            }

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

            alert(o.element);
        },
        show: function(o) {
            alert(o.element);
        },
        hide: function() {
            alert(o.element);
        }
    };

 $.fn.plugin = function( method ) {

    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    

  };

})( jQuery );

var blah = $('#hello').plugin('show'); // TypeError: o is undefined

I would want to get selection as the answer... is it possible?

EDIT:

(function($) {

    $.fn.plugin = function( method ) {

        if ( methods[method] ) {
          return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply( this, arguments );
        } else {
          $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
        }    

     }; 

     $.fn.plugin.defaults = {
        attr: 'checked',
        expected: true,
        onChange: function(){}
      }; 

    var methods = {

        init: function(options) {
            var options = $.extend({}, $.fn.plugin.defaults, options);
            var o = options;

            var $this = this;

            $this.show();
            //alert(o.attr);
        },
        show: function(options) {

            var options = $.extend({}, $.fn.plugin.defaults, options);
            var o = options;

            alert(o.expected);
        },
        hide: function(object) {
            alert(o.element);
        }
    };


})( jQuery );

reference

var blah = $('#hello').plugin('show',{expected:"#hello world"}); 

now I get #hello world (correct)

but,

var blah = $('#hello').plugin('init'); // returns nothing

I would want to get true as the answer because init is accessing show. So how do I access other methods from a method?

Run
  • 54,938
  • 169
  • 450
  • 748

1 Answers1

1

It appears to me that you are trying to reinvent extensible jquery plugins (aka jQuery UI Widgets). I can walk you though a lot of how to accomplish what you are trying to do, but it really is reinventing the wheel. The jQuery UI Widget Factory is great for this type of thing.

jQuery Widget Factory -- This is their old documenation, but it outlines the widget factory better than anything else, IMHO. They have made some minor changes to it in 1.9/1.10, but most of the concepts are still the same.

Edit

Here's my modifications to your code. I believe this does what you were looking for.

(function($) {
    var methods = {
        init: function(options) {
            var defaults = {
                element:    "selection"
            }

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

            alert("init: " + this.options.element);
        },
        show: function() {
            alert("show: "  + this.options.element);
        },
        hide: function() {
            alert("hide: " + this.options.element);
        }
    };

 $.fn.plugin = function( method ) {
    if ( methods[method] ) {
      methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    } 
    return this; // this is needed to ensure chainability
 };

})( jQuery );

var blah = $('#hello').plugin('init').plugin('show');​
Jason Whitted
  • 4,059
  • 1
  • 16
  • 16
  • thanks for the answer. I am not making any widget. I am just trying to learn using namespace in a plugin but it seems that namespace is very difficult if I want to have some basic default settings to be shared among the methods. Another trouble is - how do I call a method in another method? If I just stick to basic plugin then I have no such issues... – Run Dec 23 '12 at 03:11
  • 1
    Don't let the term `widget` fool you. A widget is merely a plugin, exactly like what you were building. But the widget factory has extensibility built into it -- solving a lot of the problems you are going to face. If you want me to show you how to get your code to work, I can do that, but if you are really interested in plugin authoring I would highly recommend widgets. I can help you with either / both -- just let me know which direction you are interested in heading. – Jason Whitted Dec 23 '12 at 03:13
  • thank you so much Jason. I would love to know better in plugin authoring before going for `widget` as I want to learn it step by step... I have done an edit in my question - I seem have managed to pass `options` among methods but ugly. Then my final problem is - how to access other methods from a method. thank you! – Run Dec 23 '12 at 03:27
  • Thanks for your edit Jason. Would you mind have a look at my edit? Thank you. – Run Dec 23 '12 at 03:36
  • 1
    Your edits look pretty good. Missing the part about chainability, which most plugin consumers expect plugins to do. – Jason Whitted Dec 23 '12 at 03:38
  • thank you Jason. how `widget` would solve problems I am facing? I just read an article - it says `namespaces` are old school... http://blog.millermedeiros.com/namespaces-are-old-school/ how come!?? – Run Dec 23 '12 at 03:53
  • 1
    Javascript doesn't really support namespaces. Different developers have engineered different ways to mimic them -- some to greater success than others. And of course everyone has their own opinion of the various methods. I created a simple widget if you would like to look through the basics of using the jQuery UI Widget Factory -- [JSFiddle](http://jsfiddle.net/nREYh/2/) – Jason Whitted Dec 23 '12 at 04:35
  • `Javascript doesn't really support namespaces` then it now makes sense! thank you. Thanks for the JSFiddle as well! Can I ask - ` _create`, `_setOption`, & `_destroy` are these functions that we have to follow when making a `widget` or are they just custom functions? – Run Dec 23 '12 at 04:45
  • 1
    Those are part of the widget factory. I created a FAQ to stackoverflow about creating a widget using the factory. If it gets published I'll send you the link. – Jason Whitted Dec 23 '12 at 04:47