0

I have simplified the code below to outline the issue. When I invoke plugin's method like this $('#element').plugin('hide'); it works, but when I call it from the inner show() method, like this.hide() it doesn't work or it calls the jQuery hide() method.

I tried var self = this, $.proxy(), apply(), call() but without success. Here is the jsBin

;(function ($, window, document, undefined) {

    var defaults = {
        type: 'standard',
    };
    var methods = {
        init: function(options){
            console.log('IN - INIT()');
            if(options){
                $.extend(defaults, options);
            }
        },
        show: function(arg){
            console.log('IN - SHOW()');         
            var $this = this; // Here might be the problem
            this.addClass(arg.type);
            this.find('.close-button').on('click', function(){
                $this.hide(); // Here might be the problem      
            });
        },
        hide: function(){
            console.log('IN - HIDE()');
        }
    };

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

}(jQuery, window, document));
hex494D49
  • 9,109
  • 3
  • 38
  • 47

1 Answers1

1

When you are calling $this.hide() within show ,it is trying to call the jquery's hide method on the element ,when you change the method to hide1 or something it throws error ,because it is looking for the method on the element as it does not exist it throws error

When you define method on plugin ,you need to call hide as plugin('hide') so that's the reason $('#box').plugin('hide') works

change the binding event of onclick of closebutton

;
(function($, window, document, undefined) {

  var defaults = {
    type: 'standard',
  };
  var methods = {
    init: function(options) {
      console.log('IN - INIT()');
      if (options) {
        $.extend(defaults, options);
      }
    },
    show: function(arg) {
      console.log('IN - SHOW()');
      var $this = this;
      this.css({
        display: 'block'
      });

      this.find('.close-button').on('click', function() {
        $this.plugin('hide'); // Here might be the problem      
      });
    },
    hide: function() {
      console.log('IN - HIDE()');
      this.css({
        display: 'none'
      });
    }
  };

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

}(jQuery, window, document));

$('#box').plugin('show', {type: 'normal'});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="box">
  <span class="close-button">HIDE</span>
</div>

Instead of storing this reference into a variable

change the scope of this using this code

this.find('.close-button').click($.proxy(function () {
     this.plugin('hide');
 },$this));

Hope this helps

Geeky
  • 7,420
  • 2
  • 24
  • 50
  • Thanks for your time but seems it doesn't work. Here is the Here is the jsBin Try from the console `$('#box').plugin('show', {type: 'normal'});` then try to close the box using the inner link. But `$('#box').plugin('hide');` works. – hex494D49 Dec 08 '16 at 09:40
  • It is trying to look for the method on the element,so that's why native hide is working but not the plugin's ..When there is a method on the plugin we have to call as $('#box').plugin('hide')..check this http://stackoverflow.com/questions/1117086/how-to-create-a-jquery-plugin-with-methods – Geeky Dec 08 '16 at 16:00
  • Hard coding the plugin name doesn't seem a good practice to me. Anyhow, I'm accepting you answer since you were the only one trying to provide a solution. Thanks. – hex494D49 Dec 10 '16 at 16:26