Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery plugin creation and public facing methods

I have created a plugin to convert an HTML select box into a custom drop down using DIV's.

All works well, but i'd like to make it a little better. see my jsFiddle

At the end of the plugin I have 2 methods, slideDownOptions & slideUpOptions, I would like to make these available outside of the plugin so other events can trigger the action.

Im getting a little confused how to do this and more specifically how to call the methods from both within the plugin AND from outside of the plugin.

Any help always appreciated

like image 981
sygad1 Avatar asked Dec 03 '22 01:12

sygad1


2 Answers

Think about refactoring your plugin using object oriented code. With this you can make API for your plugins like jQuery UI API. So you could access to plugin methods like:

$('select').customSelect(); // apply plugin to elements
$('select').customSelect('resetOpacity'); // call method resetOpacity();
$('select').customSelect('setOpacity', 0.5); // call method with arguments

Basic template for creating such plugins will look like following:

// plugin example
(function($){
    // custom select class
    function CustomSelect(item, options) {
        this.options = $.extend({
            foo: 'bar'
        }, options);
        this.item = $(item);
        this.init();
    }
    CustomSelect.prototype = {
        init: function() {
            this.item.css({opacity:0.5});
        },
        resetOpacity: function() {
            this.setOpacity('');
        },
        setOpacity: function(opacity) {
            this.item.css({opacity:opacity});
        }
    }

    // jQuery plugin interface
    $.fn.customSelect = function(opt) {
        // slice arguments to leave only arguments after function name
        var args = Array.prototype.slice.call(arguments, 1);
        return this.each(function() {
            var item = $(this), instance = item.data('CustomSelect');
            if(!instance) {
                // create plugin instance and save it in data
                item.data('CustomSelect', new CustomSelect(this, opt));
            } else {
                // if instance already created call method
                if(typeof opt === 'string') {
                    instance[opt].apply(instance, args);
                }
            }
        });
    }

}(jQuery));

// plugin testing
$('select').customSelect();

Working JS fiddle here: http://jsfiddle.net/XsZ3Z/

like image 85
Inferpse Avatar answered Dec 23 '22 22:12

Inferpse


You gonna have to refactor the code to get it working. Consider using the jQuery Boilerplate:

;(function ( $, window, undefined ) {

  var pluginName = 'convertSelect',
  document = window.document,
  defaults = {
    propertyName: "value"
  };

  function Plugin( element, options ) {
    this.element = element;
    this.options = $.extend( {}, defaults, options) ;

    this._defaults = defaults;
    this._name = pluginName;

    this.init();
  }

  Plugin.prototype = {

    // Private methods start with underscore
    _generateMarkup: function() {

      // you can access 'this' which refers to the constructor
      // so you have access the all the properties an methods
      // of the prototype, for example:
      var o = this.options

    },

    // Public methods
    slideDownOptions: function() { ... }

  }

  $.fn[ pluginName ] = function ( options ) {
    return this.each(function () {
      if (!$.data( this, 'plugin_' + pluginName ) ) {
        $.data( this, 'plugin_' + pluginName, new Plugin( this, options ) );
      }
    });
  };

}(jQuery, window));

Then you can can call public methods like so:

var $select = $('select').convertSelect().data('plugin_convertSelect');
$select.slideDownOptions();

I had a similar problem with a project of mine, I recently had to refactor the whole thing because I was polluting the jQuery namespace with too many methods. The jQuery Boilerplate works very well, it's based on the official jQuery guide but with some twists. If you wanna see this plugin pattern in action take a look at https://github.com/elclanrs/jq-idealforms/tree/master/js/src.

like image 25
elclanrs Avatar answered Dec 23 '22 20:12

elclanrs