/ Gists / Patterns:
On gists

Patterns:

jQuery-plugins

capty.js Raw #

/**
 * jQuery Capty - A Caption Plugin - http://wbotelhos.com/capty
 * ---------------------------------------------------------------------------------
 *
 * jQuery Capty is a plugin that creates captions over the images.
 *
 * Licensed under The MIT License
 *
 * @version         0.2.1
 * @since           12.18.2010
 * @author          Washington Botelho dos Santos
 * @documentation   wbotelhos.com/capty
 * @twitter         twitter.com/wbotelhos
 * @license         opensource.org/licenses/mit-license.php MIT
 * @package         jQuery Plugins
 *
 * Usage with default values:
 * ---------------------------------------------------------------------------------
 * $('#capty').capty();
 *
 * <img id="capty" src="image.jpg" alt="Super Mario Bros.&reg;" width="150" height="150"/>
 *
 */

;(function($) {

	$.fn.capty = function(settings) {
		var options = $.extend({}, $.fn.capty.defaults, settings);

		if (this.length == 0) {
			debug('Selector invalid or missing!');
			return;
		} else if (this.length > 1) {
			return this.each(function() {
				$.fn.capty.apply($(this), [settings]);
			});
		}

		var $this		= $(this),
			name		= $this.attr('name'),
			$caption	= $('<div class="' + options.cCaption + '"/>'),
			$elem		= $this;

		if ($this.parent().is('a')) {
			$elem = $this.parent();
		}

		var $image		= $elem.wrap('<div class="' + options.cImage + '"/>').parent(),
			$wrapper	= $image.wrap('<div class="' + options.cWrapper + '"/>').parent();

		$wrapper.css({
			height:		$this.height(),
			overflow:	'hidden',
			position:	'relative',
			width:		$this.width()
		});

		$caption.css({
			height:		options.height,
			opacity:	options.opacity,
			position:	'relative'
		})
		.click(function(evt) {
			evt.stopPropagation();
		})
		.appendTo($wrapper);

		if (name) {
			var $content = $(name);

			if ($content.length) {
				$content.appendTo($caption);
			} else {
				$caption.html('<span style="color: #F00;">Content invalid or missing!</span>');
			}
		} else {
			$caption.html($this.attr('alt'));
		}

		if (options.prefix) {
			$caption.prepend(options.prefix);
		}

		if (options.sufix) {
			$caption.append(options.sufix);
		}

		if (options.animation == 'slide') {
			$wrapper.hover(
				function() {
					$caption.animate({ top: (-1 * options.height) }, { duration: options.speed, queue: false });
				},
	    		function() {
					$caption.animate({ top: 0 }, { duration: options.speed, queue: false });
				}
	    	);
		} else if (options.animation == 'fade') {
			$caption.css({
				opacity:	0,
				top:		(-1 * options.height) + 'px'
			});

			$wrapper.hover(
				function() {
					$caption.stop().animate({ opacity: options.opacity }, options.speed);
				},
	    		function() {
					$caption.stop().animate({ opacity: 0 }, options.speed);
				}
	    	);
		} else if (options.animation == 'fixed') {
			$caption.css('top', (-1 * options.height) + 'px');
		} else {
			debug($this.attr('id') + ': invalid animation!');
		}

		return $this;
	};

	function debug(message) {
		if (window.console && window.console.log) {
			window.console.log(message);
		}
	};

	$.fn.capty.defaults = {
		animation:	'slide',
		cCaption:	'capty-caption',
		cImage:		'capty-image',
		cWrapper:	'capty-wrapper',
		height:		30,
		opacity:	.7,
		prefix:		'',
		speed:		200,
		sufix:		''
	};

})(jQuery);

checkall.js Raw #

/*!
 * jQuery Checkall - A Checkbox Checker
 *
 * The MIT License
 *
 * author:  Washington Botelho
 * github:  wbotelhos/checkall
 * version: 0.1.0
 *
 */

function Checkall(element, options) {
  'use strict';

  this.self  = $(element);
  this.opt   = $.extend(true, {}, $.fn.checkall.defaults, options);
  this.all   = this.self.find(this.opt.all);
  this.items = this.self.find(this.opt.item);
  this.total = this.items.length;
}

Checkall.prototype._bindAll = function() {
  'use strict';

  var that = this;

  this.all.on('change', function() {
    that.items.prop('checked', this.checked);
  });
};

Checkall.prototype._bindItems = function() {
  'use strict';

  this.items.on('change', this._inspect.bind(this));
};

Checkall.prototype._create = function() {
  'use strict';

  this._bindAll();
  this._bindItems();
  this._inspect();
};

Checkall.prototype._inspect = function() {
  'use strict';

  var checked = this.items.filter(':checked');

  this.all.prop('checked', checked.length === this.total);
};

(function($) {
  'use strict';

  $.fn.checkall = function(options) {
    var
      args   = Array.prototype.slice.call(arguments, 1),
      method = Checkall.prototype[options];

    return this.each(function() {
      var
        self     = $(this),
        instance = self.data('checkall');

      if (!instance) {
        instance = new Checkall(this, options);

        instance._create();

        self.data('checkall', instance);
      }

      if (method) {
        method.apply(instance, args);
      } else if (options && typeof options !== 'object') {
        $.error('Method "' + options + '" not found.');
      }
    });
  };

  $.fn.checkall.defaults = {
    all:  '.checkall__all',
    item: '.checkall__item'
  };
})(jQuery);

checky.js Raw #

/*!
 * jQuery Checky - A Checkbox Restrictor
 *
 * The MIT License
 *
 * @author  : Washington Botelho
 * @doc     : http://wbotelhos.com/checky
 * @version : 0.1.0
 *
 */

// done
function Checky(element, options) {
  'use strict';

  this.element  = element;
  this.self     = $(element);
  this.opt      = $.extend(true, {}, $.fn.checky.defaults, options);

  this.items    = this.self.find(this.opt.item);
  this.total    = this.items.length;
  this.checkeds = [];
}

// done
Checky.prototype._addInitials = function() {
  'use strict';

  var that = this;

  this._checkeds().each(function() {
    that.checkeds.push(this);
  });
};

// done
Checky.prototype._addOrRemove = function(item) {
  'use strict';

  if (item.checked) {
    this.checkeds.push(item);
  } else {
    var index = this.checkeds.indexOf(item);

    if (index >= 0) {
      this.checkeds.splice(index, 1);
    }

    this._enableOrDisable();
  }
};

// done
Checky.prototype._bindItems = function() {
  'use strict';

  var that = this;

  that.items.on('change', function() {
    if (that.opt.type === 'radio') {
      that._clean(this);
    } else {
      that._addOrRemove(this);
      that._inspect();
    }
  });
};

// done
Checky.prototype._clean = function(item) {
  'use strict';

  this.items.filter(function() {
    return this !== item;
  }).removeAttr('checked');
};

// done
Checky.prototype._configure = function() {
  'use strict';

  if (this.opt.type === 'radio') {
    this.opt.min = 0;
    this.opt.max = 1;
  }
};

// done
Checky.prototype._create = function() {
  'use strict';

  this._configure();
  this._bindItems();

  if (this.opt.type !== 'radio') {
    this._addInitials();
    this._inspect();
  }
};

// done
Checky.prototype._checkeds = function() {
  'use strict';

  return this.items.filter(':checked');
};

// done
Checky.prototype._disable = function(boo) {
  'use strict';

  boo = boo === undefined || boo;

  for (var i = 0; i < this.items.length; i++) {
    if (this.checkeds.indexOf(this.items[i]) < 0) {
      this.items[i].disabled = boo;
    }
  }
};

// done
Checky.prototype._enableOrDisable = function() {
  'use strict';

  if (this.opt.style === 'disable') {
    this._disable(false);
  }
};

// done
Checky.prototype._max = function() {
  'use strict';

  return this.opt.max && this._checkeds().length >= this.opt.max;
};

// done
Checky.prototype._min = function() {
  'use strict';

  return this.opt.min && this._checkeds().length < this.opt.min;
};

// done
Checky.prototype._select = function(item) {
  'use strict';

  item.checked = true;

  this.checkeds.push(item);
};

// done
Checky.prototype._inspect = function() {
  'use strict';

  if (this._max()) {
    this['_' + this.opt.style].call(this);
  } else if (this._min()) {
    var uncheckeds = this._uncheckeds();

    for (var i = 0; i < this._toSelect(); i++) {
      this._select(uncheckeds[i]);
    }
  }
};

// done
Checky.prototype._toSelect = function() {
  'use strict';

  if (!this.opt.min) {
    return 0;
  }

  return this.opt.min - this._checkeds().length;
};

// done
Checky.prototype._uncheckeds = function() {
  'use strict';

  return this.items.filter(':not(:checked)');
};

// done
Checky.prototype._unselect = function() {
  'use strict';

  var item = this.checkeds.shift();

  item.checked = false;
};

(function($) {
  'use strict';

  // done
  $.fn.checky = function(options) {
    var
      args   = Array.prototype.slice.call(arguments, 1),
      method = Checky.prototype[options];

    return this.each(function() {
      var
        self     = $(this),
        instance = self.data('checky');

      if (!instance) {
        instance = new Checky(this, options);

        instance._create();

        self.data('checky', instance);
      }

      if (method) {
        method.apply(instance, args);
      } else if (options && typeof options !== 'object') {
        $.error('Method ' + options + ' does not exist!');
      }
    });
  };

  // done
  $.fn.checky.defaults = {
    item  : '.checky',
    max   : undefined,
    min   : undefined,
    style : 'disable',
    type  : 'checkbox'
  };
})(jQuery);

complety.js Raw #

/*!
 * jQuery Complety - An Auto Complete Plugin
 *
 * The MIT License
 *
 * @author  : Washington Botelho
 * @doc     : http://wbotelhos.com/complety
 * @version : 0.1.1
 *
 */

;(function() {
  'use strict';

  var keys = {
    ALT:       18,
    BACKSPACE: 8,
    COMMAND:   91,
    CTRL:      17,
    DOWN:      40,
    ENTER:     13,
    ESC:       27,
    LEFT:      37,
    RIGHT:     39,
    SHIFT:     16,
    TAB:       9,
    UP:        38
  };

  function Complety(el, options) {
    this.el   = el;
    this.self = $(el);
    this.opt  = $.extend(true, {}, $.fn.complety.defaults, options);
  }

  Complety.prototype = {
    _able: function() {
      return this.currentValue && this.currentValue.length >= this.opt.minChars;
    },

    _ajax: function(url) {
      this.loader('start');

      var ajax = $.ajax(url);

      if (this.xhrs.length) {
        this.abort();
      }

      this.xhrs.push(ajax);

      return ajax;
    },

    _always: function(json) {
      this.loader('stop');

      if ($.isFunction(this.opt.ajax.always)) {
        this.opt.ajax.always.call(this, json);
      }
    },

    _assigns: function() {
      this.xhrs = [];
    },

    _binds: function() {
      var that = this;

      this.self.on('keydown.complety', function(evt) {
        var
          key     = evt.which || evt.keyCode,
          stopped = [keys.ENTER, keys.DOWN, keys.UP];

        if (stopped.indexOf(key) >= 0) {
          that._stop(evt);
        }
      });

      this.self.on('keyup.complety', function(evt) {
        that._onKeyUp(evt, this.value);
      });

      this.target.on('click.complety', this.opt.wrappers.item, function() {
        that._select(this);
      });

      this.target.on('mouseenter.complety', this.opt.wrappers.item, function() {
        that._hover(this);
      });
    },

    _cache: function(json) {
      this.opt.cache[this.url()] = json;
    },

    _clearDelay: function() {
      clearTimeout(this.timeout);
    },

    _create: function() {
      this._findWrappers();
      this._assigns();
      this._prepare();
      this._binds();
      this._map();

      return this;
    },

    _decide: function(key) {
      var action = this.actions[key];

      if (action) {
        action.call(this);
      } else if (!this._isIgnoredKey(key)) {
        this._search();
      }
    },

    _done: function(json) {
      if (json.length) {
        this._cache(json);
        this._render(json);
      } else {
        this._none();
      }

      if ($.isFunction(this.opt.ajax.done)) {
        this.opt.ajax.done.call(this, json);
      }
    },

    _fail: function(json) {
      if (json.statusText !== 'abort' && $.isFunction(this.opt.ajax.fail)) {
        this.opt.ajax.fail.call(this, json);
      }
    },

    _findWrappers: function() {
      this._setFieldWrapper();
      this._setWrapper();
      this._setNoneWrapper();
      this._setTargetWrapper();
    },

    _getValue: function(suggestion) {
      if ($.isFunction(this.opt.functions.getValue)) {
        return this.opt.functions.getValue.call(this, suggestion);
      }

      return suggestion.id;
    },

    _highlight: function(suggestion) {
      var highlight = $.extend(true, {}, suggestion);

      for (var i = 0; i < this.opt.keys.length; i++) {
        var
          path  = this.opt.keys[i].split('.'),
          regex = new RegExp('(' + this.self.val() + ')', 'i'),
          value = suggestion;

        for (var j = 0; j < path.length; j++) {
          value = value[path[j]];
        }

        if (value) {
          highlight[this.opt.keys[i]] = value.replace(regex, '<b>$1</b>');
        } else {
          $.error('Missing key: ' + this.opt.keys[i]);
        }
      }

      return highlight;
    },

    _highlights: function() {
      var that = this;

      return this.currentSuggestions.map(function(suggestion) {
        return that._highlight(suggestion);
      });
    },

    _highlightItem: function(number) {
      var
        index = number % this.target.data('total'),
        clazz = this.opt.wrappers.itemSelected.replace('.', '');

      this
      .target
      .data('current', index)
        .find(this.opt.wrappers.item)
        .removeClass(clazz)
          .eq(index)
          .addClass(clazz);
    },

    _hover: function(item) {
      var items = this.target.find(this.opt.wrappers.item);

      items.removeClass(this.opt.wrappers.itemSelected.replace('.', ''));

      $(item).addClass(this.opt.wrappers.itemSelected.replace('.', ''));
    },

    _hovered: function() {
      return this.target.find(this.opt.wrappers.itemSelected);
    },

    _isIgnoredKey: function(key) {
      return [
        keys.ALT,
        keys.COMMAND,
        keys.CTRL,
        keys.LEFT,
        keys.RIGHT,
        keys.SHIFT
      ].indexOf(key) >= 0;
    },

    _map: function() {
      if (!this.actions || !Object.keys(this.actions).length) {
        this.actions = {};

        this.actions[keys.ESC]  = this.hide;
        this.actions[keys.TAB]  = this.hide;
        this.actions[keys.UP]   = this._moveUp;
        this.actions[keys.DOWN] = this._moveDown;

        this.actions[keys.ENTER] = function() {
          var item = this._hovered();

          if (item.length) {
            this._select(item);
            this.hide();
          }
        };
      }
    },

    _current: function() {
      var hovered = this._hovered();

      return (hovered && hovered.index()) || this.target.data('current');
    },

    _moveDown: function() {
      var current = this._current();

      this.show();

      this._highlightItem((current === undefined ? -1 : current) + 1);
    },

    _moveUp: function() {
      var current = this._current();

      this.show();

      this._highlightItem((current || this.target.data('total')) - 1);
    },

    _none: function() {
      var value = this.self.val();

      this.hide();
      this.none.html(this.opt.templates.none({ q: value })).show();
      this.self.trigger('none', [value, this]);
    },

    _onKeyUp: function(evt, value) {
      var key = evt.which || evt.keyCode;

      this.currentValue = $.trim(value);

      // if (this.currentValue) { // serch field cleans on esc so the items does not hide
      this._decide(key);
      this._stop(evt);
      // }
    },

    _prepare: function() {
      this.self.prop('autocomplete', 'off');

      if (this.opt.suggestion) {
        this.suggest(this.opt.suggestion);
      }
    },

    _query: function() {
      if (this._able()) {
        var cached = this.opt.cache[this.url()];

        if (cached) {
          this._always(cached);
          this._done(cached);
        } else {
          var
            ajax = this._ajax(this.url()),
            that = this;

          ajax.always(function(json) {
            that._always(json);
          });

          ajax.done(function(json) {
            that._done(json);
          });

          ajax.fail(function(json) {
            that._fail(json);
          });
        }
      }
    },

    _render: function(json) {
      this.currentSuggestions = json;

      var html = this.opt.templates.search({ list: this._highlights() });

      this.none.hide().empty();

      this.target.html(html).data('total', json.length);

      this.show();
    },

    _search: function() {
      if (this.timeout) {
        this.loader('stop');

        this._clearDelay();
      }

      this.timeout = setTimeout(this._query.bind(this), this.opt.delay);
    },

    _setFieldWrapper: function() {
      this.field = this.self.parent(this.opt.wrappers.field);

      if (!this.field.length) {
        var wrapper = this._wrapperFor('field');

        this.field = this.self.wrap(wrapper).parent();
      }
    },

    _select: function(item) {
      var index = this.target.find(this.opt.wrappers.item).index(item);

      this.suggest(this.currentSuggestions[index]);
    },

    _selected: function(suggestion) {
      this.hide();

      this.currentSuggestion = suggestion;

      this.self.trigger('selected', [suggestion, this]);

      if ($.isFunction(this.opt.callbacks.selected)) {
        this.opt.callbacks.selected.call(this, suggestion);
      }
    },

    _setNoneWrapper: function() {
      this.none = this.wrapper.find(this.opt.wrappers.none);

      if (!this.none.length) {
        this.none = this._wrapperFor('none').appendTo(this.wrapper);
      }
    },

    _setTargetWrapper: function() {
      this.target = this.wrapper.find(this.opt.wrappers.target);

      if (!this.target.length) {
        this.target = this._wrapperFor('target').appendTo(this.wrapper);
      }
    },

    _setWrapper: function() {
      this.wrapper = this.field.closest(this.opt.wrappers.wrapper);

      if (!this.wrapper.length) {
        var wrapper = this._wrapperFor('wrapper');

        this.wrapper = this.field.wrap(wrapper).parent();
      }
    },

    _stop: function(evt) {
      evt.preventDefault();
      evt.stopImmediatePropagation();
      evt.stopPropagation();
    },

    _wrapperFor: function(name) {
      return $('<div />', { 'class': this.opt.wrappers[name].replace('.', '') });
    },

    abort: function() {
      for (var i = 0; i < this.xhrs.length; i++) {
        this.xhrs[i].abort();
      }

      this.xhrs = [];

      return this;
    },

    hide: function() {
      this._clearDelay();
      this.target.hide();
      this.none.hide();

      this.visible = false;

      return this;
    },

    loader: function(action) {
      var boo = action === 'start';

      // this.loading.toggle(boo);

      if (boo) {
        this.field.addClass(this.opt.wrappers.loading);
      } else {
        this.field.removeClass(this.opt.wrappers.loading);
      }

      return this;
    },

    readonly: function(boo) {
      this.self.prop('readonly', boo);

      return this;
    },

    show: function() {
      if (!this.visible && this._able()) {
        this.target.show();

        this.visible = true;
      }

      return this;
    },

    suggest: function(suggestion) {
      var value = this._getValue(suggestion);

      this.self.val(value);

      this._selected(suggestion);
    },

    suggestion: function() {
      return this.currentSuggestion;
    },

    suggestions: function() {
      return this.currentSuggestions;
    },

    url: function() {
      return (this.self.data('url') || this.opt.url).replace(':q', this.currentValue);
    },

    wrappers: function() {
      return {
        field:   this.field,
        loading: this.loading,
        none:    this.none,
        target:  this.target,
        wrapper: this.wrapper
      };
    }
  };

  (function($) {
    $.fn.complety = function(options) {
      var instances = this.map(function() {
        var
          self     = $(this),
          instance = self.data('complety');

        if (!instance) {
          instance = new Complety(this, options);

          instance._create();

          self.data('complety', instance);
        }

        return instance;
      });

      if (instances.length === 1) {
        return instances[0];
      }

      return instances;
    };

    $.fn.complety.defaults = {
      cache:      {},
      delay:      300,
      keys:       undefined,
      minChars:   1,
      suggestion: undefined,
      url:        undefined,

      callbacks: {
        selected: undefined
      },

      functions: {
        getValue: undefined
      },

      ajax: {
        always: undefined,
        done:   undefined,
        fail:   undefined
      },

      wrappers: {
        field:        '.complety__field',
        item:         '.complety__item',
        itemSelected: '.complety__item--selected',
        list:         '.complety__list',
        loading:      '.complety__loading',
        none:         '.complety__none',
        target:       '.complety__target',
        wrapper:      '.complety'
      }
    };
  })(jQuery);
})();

skeleton.js Raw #

/*!
 * AW {{PROJECTNAME}}
 *
 *
 * @author  {{firstname lastname}} <{{email}}>
 * @version  1.0.0
 *
 */

 /*
    {{PLUGIN}} => realname of project, eg: awBestPlugin
 */

;(function() {
    'use strict';

    function {{PLUGIN}}(element, options) {
        this.self  = $(element);
        this.settings   = $.extend(true, {}, $.fn.{{PLUGIN}}.defaults, options);

    }


    {{PLUGIN}}.prototype = {
        
        /* PRIVATE METHODS */
        _create: function() { 
           
        }

  
        /* PUBLIC METHODS */
      
    };


    (function ($) {
        $.fn.{{PLUGIN}} = function(options) {
            var
            args   = Array.prototype.slice.call(arguments, 1),
            method = {{PLUGIN}}.prototype[options];

            
            return this.each(function() {
                var self     = $(this);
                var instance = self.data('{{PLUGIN}}');

                if (!instance) {
                    instance = new {{PLUGIN}}(this, options);
                    instance._create();
                    self.data('{{PLUGIN}}', instance);
                }

                if (method && options.substring(0, 1) == '_') 
                    $.error('Cannot use private method "' + options + '" outside of object');
                
                if (method) {
                    method.apply(instance, args);
                } else if (options && typeof options !== 'object') {
                    $.error('Method "' + options + '" not found.');
                }
            });
        };

        $.fn.{{PLUGIN}}.defaults = {
 
        };
    })(jQuery);
})();

aw-filters.js Raw #

/*!
 * AW Eshop Filters
 *
 *
 * @author  Roman Janko <janko@andweb.cz>
 * @since  30.01.2019 09:59:25
 * @version  1.0.0
 *
 */

;(function() {
    'use strict';

    function awEshopFilters(element, options) {
        this.self            = $(element);
        this.settings        = $.extend(true, {}, $.fn.awEshopFilters.defaults, options);
        
        this.mainButton            = $(this.settings.mainButton);
        this.filterBody            = $(this.settings.filterBody);
        this.filterList            = $(this.settings.filterList);
        this.filterGroups          = $(this.settings.filterGroups);
        this.selectedFilterWrapper = $(this.settings.selectedFilterWrapper);
        this.selectedFilterHeading = $(this.settings.selectedFilterHeading);
        this.selectedFilterSet     = $(this.settings.selectedFilterSet);
        this.deleteAllFiltersBtn   = $(this.settings.deleteAllFiltersBtn);
    }


    awEshopFilters.prototype = {
        
        /* PRIVATE METHODS */
        _create: function() { 
            this._bindMainButton();
            this._bindFilterLinkClick();
            this._bindFilterGroupItemClick();
            this._bindFilterGroupItemSliderChange();
            this._bindDeleleteAllFiltersBtn();

            this._updateFilterSetState();
        },

        _bindMainButton: function() {
            var that = this;

            this.mainButton.on('click', function(e) {
                e.preventDefault();
                
                var $this = $(this);
                var opened = $this.data('state') || 'closed'; // default state
                var effect = that.settings.animation ? 'slideToggle' : 'toggle';
                if (opened == 'closed') {
                    $this.data('state', 'opened');
                    $this.find('i').removeClass().addClass(that.settings.mainButtonClasses.opened);
                } else {            
                    $this.data('state', 'closed');
                    $this.find('i').removeClass().addClass(that.settings.mainButtonClasses.closed);
                }

                that.filterBody[effect]();
                
            });
        },

        /**
         * Current active list item from filter on left side
         */
        _getGroup: function(groupId) {
            var item = this.filterList
                .find('li[data-groupid="'+groupId+'"]')
                .children('a');

            return {
                'rank': item.parent().data('rank'),
                'id': item.parent().data('groupid'),
                'text': item.text(),
                'item': item
            }
        },

        _bindFilterLinkClick: function() {
            var that = this;

            this.filterList.find('a').on('click', function(e) {
				e.preventDefault();
				
				$('html, body').animate({
					scrollTop: that.filterList.offset().top - 100
				});

                var $this = $(this);
                var $parent = $this.parent();
                var hasChildren = $parent.data('has-children') || 0;
                var id = $parent.data('groupid');

                that.filterList
                    .find('li')
                    .removeClass('active');
                
                 $parent
                    .addClass('active');
                
                that.filterGroups
                    .hide();

                that.filterGroups
                    .children()
                    .hide();

                if (hasChildren) {
                    $parent
                        .children('ul')
                        .toggle();

                    var isVisible = $parent.children('ul').is(":visible") || 0;

                    $parent
                        .children('a')
                        .children('i')
                        .removeClass(function(i, s) {
                            $(this)
                                .removeClass(that.settings.filterLinkChildrenClass.closed)
                                .removeClass(that.settings.filterLinkChildrenClass.opened)
                                .addClass(
                                            !isVisible ? that.settings.filterLinkChildrenClass.opened : that.settings.filterLinkChildrenClass.closed);
                        });
                }    

                var foundedSomeGroup = that.filterGroups
                    .find('[data-groupid="'+id+'"]');

                if (foundedSomeGroup.length) {
                    that.filterGroups.show();
                    foundedSomeGroup.show();
                }                   
                
            }).filter(':first').trigger('click');
        },

        _group: function() {
            var that = this;

            var add = function(group) {
                var newGroup = $('<div>').attr('data-group', group.id)
                                    .attr('data-rank', group.rank)
                                    .html('<div>' + group.text + '</div>')
                                    .appendTo(that.selectedFilterSet);
                newGroup.append('<div>');  

                return newGroup;
            };

            var exists = function(groupId) {
                var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
                return group.length > 0;
            };

            var remove = function(group) {
                group.remove();
            };  

            var removeGroupIsEmpty = function(groupId) {
                var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
                if (group.find('a').length === 0) {
                    remove(group);
                }
            };

            return {
                add: add,
                exists: exists,
                remove: remove,
                removeGroupIsEmpty: removeGroupIsEmpty
            }
            
        },

        _bindFilterGroupItemSliderChange: function() {
            var that = this;

            that.filterGroups.on('change', '.range-slider-default', function(e) {
                var $slider = $(this);
                var from = $slider.data("from"); 
                var to = $slider.data("to"); 
                var value = $slider.prop("value").split(';'); // human readable values = text values
                var group = that._getGroup($slider.data('groupid')); // curent active group
                var dataValues = $slider.data('values').split(',');

       
                // group doesnt exist yet, so we will add it   
                if (!that._group().exists(group.id)) {
                    var newGroup = that._group().add(group);
                }

                // target place for inserting a new selected range values
                var targetPlace = $(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1);
                // flush old value
                targetPlace.empty();

                // reset to default, because we are selecting default range, so we dont want to show it
                if ($slider.data('range').length === dataValues.length) {
                    that._group().removeGroupIsEmpty(group.id);
                    that._showOrHideDeleteAllFiltersBtn();
                    that._updateFilterSetState();

                    return; // SKIP ...
                }
                var tpl         = that.settings.selectedFilterItemTemplate; 
                var compiledTpl = tpl
                    .replace('{{name}}', value[0] + ' - ' + value[1])
                    .replace('{{itemid}}', $slider.data('itemid'));


                var $filterItem = $(compiledTpl);
                $filterItem.on('click.eshop-filter-item-slider', function(e) {
                    e.preventDefault();       
                    
                    that._resetSliderToDefault($slider);
                    that._removeFilterSlider($filterItem);
                    that._group().removeGroupIsEmpty(group.id);
                    that._showOrHideDeleteAllFiltersBtn();
                    that._updateFilterSetState();

                    //@TODO: callback will be applied from outside when we remove this

                }).appendTo(targetPlace);

                that._showOrHideDeleteAllFiltersBtn();
                that._updateFilterSetState();
            });
        },

        _bindFilterGroupItemClick: function() {
            var that = this;

            that.filterGroups.on('click filter:init', 'input[type="checkbox"]', function(e) {
                
                var $checkbox = $(this);
                var $label =  $checkbox.parent().next('label');
                var group = that._getGroup($checkbox.data('groupid')); // curent active group
                
                // Has been added? 
                var $hasBeenAdded = that.selectedFilterSet
                    .find('[data-itemid="'+$checkbox.data('itemid')+'"]');

                // group doesnt exist yet, so we will add it   
                if (!that._group().exists(group.id)) {
                    var newGroup = that._group().add(group);
                }

                // item has been already added?
                if ($hasBeenAdded.length > 0) {
                    that._removeFilter($hasBeenAdded);
                    that._unselectCheckbox($checkbox);
                    that._group().removeGroupIsEmpty(group.id);
                    that._updateFilterSetState();

                    that.settings.selectedFilterItemClick.apply(that, [$hasBeenAdded, $checkbox, $label]);

                    return;
                }

                var tpl         = that.settings.selectedFilterItemTemplate; 
                var compiledTpl = tpl
                    .replace('{{name}}', $label.text())
                    .replace('{{itemid}}', $checkbox.data('itemid'));

                var $filterItem = $(compiledTpl);
                $filterItem.on('click.eshop-filter-item', function(e, skipClick) {
                    e.preventDefault();       
                    
                    that._removeFilter($filterItem);
                    that._unselectCheckbox($checkbox);
                    that._group().removeGroupIsEmpty(group.id);
                    that._updateFilterSetState();

                    if(!skipClick)                    
                        that.settings.selectedFilterItemClick.apply(that, [$filterItem, $checkbox, $label]);

                }).appendTo($(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1));

                that._showOrHideDeleteAllFiltersBtn();
                that._updateFilterSetState();
                
            }).find('input[type="checkbox"]:checked').trigger('filter:init');
        },

        _bindDeleleteAllFiltersBtn: function() {
            var that = this;
            
            this.deleteAllFiltersBtn.on('click', function(e) {
                var selectedFilterItems = that._getSelectedFilterItems();
                selectedFilterItems.each(function() {
                    var $item = $(this);
                    $item.trigger('click.eshop-filter-item', [true]);
                    $item.trigger('click.eshop-filter-item-slider', [true]);
                });

                that.settings.deleteAllClick.apply(that);
            });
        },

        _unselectCheckbox: function(checkbox) {
            checkbox.prop('checked', false);
        },

        _removeFilter: function(o) {
            o.off('.click.eshop-filter-item');
            o.remove();
            this._showOrHideDeleteAllFiltersBtn();
        },

        _removeFilterSlider: function(o) {
            o.off('.click.eshop-filter-item-slider');
            o.remove();
            this._showOrHideDeleteAllFiltersBtn();
        },

        _resetSliderToDefault: function($slider) {
            $slider.data("ionRangeSlider").reset();
        },

        _showOrHideDeleteAllFiltersBtn: function() {
            var hasSomeFilterInside = this._getSelectedFilterItems();

            if (hasSomeFilterInside.length === 0)
                this.deleteAllFiltersBtn.addClass('-nod');
            else  
                this.deleteAllFiltersBtn.removeClass('-nod');  

               
        },

        _updateFilterSetState: function() {

            var hasSomeFilterInside = this._getSelectedFilterItems();
            if (hasSomeFilterInside.length === 0) {
                this.selectedFilterWrapper.addClass('nod');
                //this.selectedFilterSet.html('<p class="eshop-menu-filters__text-nothing-selected">' + this.selectedFilterSet.data('empty-text') + '</p>');
            } else {
                //this.selectedFilterSet.find('p.eshop-menu-filters__text-nothing-selected').remove();
                this.selectedFilterWrapper.removeClass('nod');
            }
        },

        _getSelectedFilterItems: function() {
            return this.selectedFilterSet.find('a[data-itemid]');
        },
  
        /* PUBLIC METHODS */
        update: function(data, cntKey) {
            for (let k in data) {
                var $input = this.filterGroups.find('[data-itemid="'+k+'"]');
                if ($input.length) {
                    this.filterGroups.find('[data-count-itemid="'+k+'"]').text(data[k][cntKey]);
                    this.selectedFilterSet.find('[data-itemid="'+k+'"]').text($input.parent().next('label').text());
                }
            }
        }
    };


    (function ($) {
        $.fn.awEshopFilters = function(options) {
            var
            args   = Array.prototype.slice.call(arguments, 1),
            method = awEshopFilters.prototype[options];

            return this.each(function() {
                var self     = $(this);
                var instance = self.data('awEshopFilters');

                if (!instance) {
                    instance = new awEshopFilters(this, options);
                    instance._create();
                    self.data('awEshopFilters', instance);
                }

                if (method && options.substring(0, 1) == '_') 
                    $.error('Cannot use private method "' + options + '" outside of object');
                
                if (method) {
                    method.apply(instance, args);
                } else if (options && typeof options !== 'object') {
                    $.error('Method "' + options + '" not found.');
                }
            });
        };

        $.fn.awEshopFilters.defaults = {
            animation: false,
            animationSpeed: 0,
            mainButton: '.eshop-menu-filters__main-button', // main toggler button =  reveal below groups, is connected with filterBody
            mainButtonClasses: {
                opened: 'fa fa-angle-down',
                closed: 'fa fa-angle-up',
            },
            filterBody: '.eshop-menu-filters__body',
            filterList: '.eshop-menu-filters__filter-list', // menu with filter links
            filterGroups: '.eshop-menu-filters__filter-groups', // aside filter groups = will be filtered by links in left menu
            filterLinkChildrenClass:  { // link with children  classes for icon 
                opened: 'fa fa-plus-square',
                closed: 'fa fa-minus-square',
            },
            selectedFilterWrapper: '.eshop-menu-filters__selected-filters', // wrapper for selected filters and textual information
            selectedFilterHeading: '.eshop-menu-filters__selected-filter-heading', // title for selected filter name
            selectedFilterSet: '.eshop-menu-filters__selected-filters-set',
            deleteAllFiltersBtn: '.eshop-menu-filters__delete-all-filters',
            selectedFilterItemTemplate: '<a href="#" class="badge badge-secondary mr-2 mb-2 p-1" data-itemid="{{itemid}}">{{name}}</a>',
            selectedFilterItemClick: function(filterItem, checkbox, label) {
            },
            deleteAllClick: function() {
            }
        };
    })(jQuery);
})();

aw-range-slider.js Raw #

/*!
 * AW RANGE SLIDER
 *
 *
 * @author  Roman Janko <janko@andweb.cz>
 * @version  1.0.0
 *
 */

 /*
    AW RANGE SLIDER - wrapper over Range Slider http://ionden.com/a/plugins/ion.rangeSlider/index.html
 */

;(function() {
    'use strict';

    function awRangeSlider(element, options) {
        this.self  = element;
        this.$self  = $(element);
        this.settings   = $.extend(true, {}, $.fn.awRangeSlider.defaults, options);
        
        this.instance = null;
        this.ourFormControls = {
            priceFrom: null,
            priceTo: null,
            select: null
        };
    }


    awRangeSlider.prototype = {
        
        /* PRIVATE METHODS */
        _create: function() { 
            
            var oldOnFinish = this.settings.onFinish;
            var that = this;

            this.settings.onFinish = function(data) {
                that.instance.trigger("finish");
                oldOnFinish.apply(this, [data]);
            };

            this.instance = this.$self.ionRangeSlider(this.settings);
            if (this.settings.sliderType == 'price') {
                this._bindOnChangePrice();
            } else {
                this._bindOnChangeDefault();
            }
        },

        _bindOnChangePrice: function() {
            var that = this;

            this.ourFormControls.priceFrom = this.$self.next(); 
            this.ourFormControls.priceTo = this.$self.next().next(); 

            this.instance.on("finish", function (e) {
                var $inp = $(this);

                var from = $inp.data("from"); 
                var to = $inp.data("to"); 

                that.ourFormControls.priceFrom.val(from).trigger('change');
                that.ourFormControls.priceTo.val(to).trigger('change');

            });
        },

        _bindOnChangeDefault: function() {
            var that = this;

            var select = this.ourFormControls.select = this.$self.next(); 
            var options = select.find('option');
            
            this._resetOptions(options);
            //this._setSelectedAllOptions(options);

            this.instance.on("finish", function (e) {
                var $inp = $(this);
                var dataValues = $inp.data('values').split(',');
                var from = $inp.data("from"); 
                var to = $inp.data("to"); 
                var values = $inp.prop("value").split(';'); // human readable values = text values
                var range = that._createRange(from, to);

                $inp.data('range', range);
                                
                that._resetOptions(options);

                // loop over selected items only when if we do not choose everything, it does not make a sense
                if (dataValues.length != range.length) {
                    range.forEach(function(i) {
                        that._setSelectedOption(options.eq(i));
                    });
                }
    
            }); 
        },

        _createRange: function(start, end) {
            var range = [];
            for (var i = start; i <= end; i++) {
                range.push(i);
            }
            return range;
        },

        _resetOptions: function(options) {
            options.prop('selected', false);
        },

        _setSelectedOption: function(option) {
            option.prop('selected', true);
        },

        _setSelectedAllOptions: function(options) {
            options.prop('selected', true);
        },

        /* PUBLIC METHODS */
        updateMinMax: function(min, max) {
            var update = {
                min: min,
                //from: min,
                max: max,
                //to: max,
            };
            
            if(this.$self.data('min') == this.$self.data('from') || update.min >= this.$self.data('from')) {
                update.from = update.min;
            }

            if(this.$self.data('max') == this.$self.data('to') || update.max <= this.$self.data('to')) {
                update.to = update.max;
            }

            this.$self.data('min', update.min);
            this.$self.data('max', update.max);

            var inst = this.$self.data("ionRangeSlider");
            
            inst.update(update);
        }
    };


    (function ($) {
        $.fn.awRangeSlider = function(options) {
            var
            args   = Array.prototype.slice.call(arguments, 1),
            method = awRangeSlider.prototype[options];

            
            return this.each(function() {
                var self     = $(this);
                var instance = self.data('awRangeSlider');

                if (!instance) {
                    instance = new awRangeSlider(this, options);
                    instance._create();
                    self.data('awRangeSlider', instance);
                }

                if (method && options.substring(0, 1) == '_') 
                    $.error('Cannot use private method "' + options + '" outside of object');
                
                if (method) {
                    method.apply(instance, args);
                } else if (options && typeof options !== 'object') {
                    $.error('Method "' + options + '" not found.');
                }
            });
        };

        $.fn.awRangeSlider.defaults = {
            sliderType: 'price' // price || default
        };
    })(jQuery);
})();

svg-rating.js Raw #

/*
 *  jQuery StarRatingSvg v1.2.0
 *
 *  http://github.com/nashio/star-rating-svg
 *  Author: Ignacio Chavez
 *  hello@ignaciochavez.com
 *  Licensed under MIT
 */

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

  'use strict';

  // Create the defaults once
  var pluginName = 'starRating';
  var noop = function(){};
  var defaults = {
    totalStars: 5,
    useFullStars: false,
    starShape: 'straight',
    emptyColor: 'lightgray',
    hoverColor: 'orange',
    activeColor: 'gold',
    ratedColor: 'crimson',
    useGradient: true,
    readOnly: false,
    disableAfterRate: true,
    baseUrl: false,
    starGradient: {
      start: '#FEF7CD',
      end: '#FF9511'
    },
    strokeWidth: 4,
    strokeColor: 'black',
    initialRating: 0,
    starSize: 40,
    callback: noop,
    onHover: noop,
    onLeave: noop
  };

	// The actual plugin constructor
  var Plugin = function( element, options ) {
    var _rating;
    var newRating;
    var roundFn;

    this.element = element;
    this.$el = $(element);
    this.settings = $.extend( {}, defaults, options );

    // grab rating if defined on the element
    _rating = this.$el.data('rating') || this.settings.initialRating;

    // round to the nearest half
    roundFn = this.settings.forceRoundUp ? Math.ceil : Math.round;
    newRating = (roundFn( _rating * 2 ) / 2).toFixed(1);
    this._state = {
      rating: newRating
    };

    // create unique id for stars
    this._uid = Math.floor( Math.random() * 999 );

    // override gradient if not used
    if( !options.starGradient && !this.settings.useGradient ){
      this.settings.starGradient.start = this.settings.starGradient.end = this.settings.activeColor;
    }

    this._defaults = defaults;
    this._name = pluginName;
    this.init();
  };

  var methods = {
    init: function () {
      this.renderMarkup();
      this.addListeners();
      this.initRating();
    },

    addListeners: function(){
      if( this.settings.readOnly ){ return; }
      this.$stars.on('mouseover', this.hoverRating.bind(this));
      this.$stars.on('mouseout', this.restoreState.bind(this));
      this.$stars.on('click', this.handleRating.bind(this));
    },

    // apply styles to hovered stars
    hoverRating: function(e){
      var index = this.getIndex(e);
      this.paintStars(index, 'hovered');
      this.settings.onHover(index + 1, this._state.rating, this.$el);
    },

    // clicked on a rate, apply style and state
    handleRating: function(e){
      var index = this.getIndex(e);
      var rating = index + 1;

      this.applyRating(rating, this.$el);
      this.executeCallback( rating, this.$el );

      if(this.settings.disableAfterRate){
        this.$stars.off();
      }
    },

    applyRating: function(rating){
      var index = rating - 1;
      // paint selected and remove hovered color
      this.paintStars(index, 'rated');
      this._state.rating = index + 1;
      this._state.rated = true;
    },

    restoreState: function(e){
      var index = this.getIndex(e);
      var rating = this._state.rating || -1;
      // determine star color depending on manually rated
      var colorType = this._state.rated ? 'rated' : 'active';
      this.paintStars(rating - 1, colorType);
      this.settings.onLeave(index + 1, this._state.rating, this.$el);
    },

    getIndex: function(e){
      var $target = $(e.currentTarget);
      var width = $target.width();
      var side = $(e.target).attr('data-side');
      var minRating = this.settings.minRating;

      // hovered outside the star, calculate by pixel instead
      side = (!side) ? this.getOffsetByPixel(e, $target, width) : side;
      side = (this.settings.useFullStars) ? 'right' : side ;

      // get index for half or whole star
      var index = $target.index() - ((side === 'left') ? 0.5 : 0);

      // pointer is way to the left, rating should be none
      index = ( index < 0.5 && (e.offsetX < width / 4) ) ? -1 : index;

      // force minimum rating
      index = ( minRating && minRating <= this.settings.totalStars && index < minRating ) ? minRating - 1 : index;
      return index;
    },

    getOffsetByPixel: function(e, $target, width){
      var leftX = e.pageX - $target.offset().left;
      return ( leftX <= (width / 2) && !this.settings.useFullStars) ? 'left' : 'right';
    },

    initRating: function(){
      this.paintStars(this._state.rating - 1, 'active');
    },

    paintStars: function(endIndex, stateClass){
      var $polygonLeft;
      var $polygonRight;
      var leftClass;
      var rightClass;

      $.each(this.$stars, function(index, star){
        $polygonLeft = $(star).find('[data-side="left"]');
        $polygonRight = $(star).find('[data-side="right"]');
        leftClass = rightClass = (index <= endIndex) ? stateClass : 'empty';

        // has another half rating, add half star
        leftClass = ( index - endIndex === 0.5 ) ? stateClass : leftClass;

        $polygonLeft.attr('class', 'svg-'  + leftClass + '-' + this._uid);
        $polygonRight.attr('class', 'svg-'  + rightClass + '-' + this._uid);

      }.bind(this));
    },

    renderMarkup: function () {
      var s = this.settings;
      var baseUrl = s.baseUrl ? location.href.split('#')[0] : '';

      // inject an svg manually to have control over attributes
      var star = '<div class="jq-star" style="width:' + s.starSize+ 'px;  height:' + s.starSize + 'px;"><svg version="1.0" class="jq-star-svg" shape-rendering="geometricPrecision" xmlns="http://www.w3.org/2000/svg" ' + this.getSvgDimensions(s.starShape) +  ' stroke-width:' + s.strokeWidth + 'px;" xml:space="preserve"><style type="text/css">.svg-empty-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_1_);}.svg-hovered-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_2_);}.svg-active-' + this._uid + '{fill:url(' + baseUrl + '#' + this._uid + '_SVGID_3_);}.svg-rated-' + this._uid + '{fill:' + s.ratedColor + ';}</style>' +

      this.getLinearGradient(this._uid + '_SVGID_1_', s.emptyColor, s.emptyColor, s.starShape) +
      this.getLinearGradient(this._uid + '_SVGID_2_', s.hoverColor, s.hoverColor, s.starShape) +
      this.getLinearGradient(this._uid + '_SVGID_3_', s.starGradient.start, s.starGradient.end, s.starShape) +
      this.getVectorPath(this._uid, {
        starShape: s.starShape,
        strokeWidth: s.strokeWidth,
        strokeColor: s.strokeColor
      } ) +
      '</svg></div>';

      // inject svg markup
      var starsMarkup = '';
      for( var i = 0; i < s.totalStars; i++){
        starsMarkup += star;
      }
      this.$el.append(starsMarkup);
      this.$stars = this.$el.find('.jq-star');
    },

    getVectorPath: function(id, attrs){
      return (attrs.starShape === 'rounded') ?
        this.getRoundedVectorPath(id, attrs) : this.getSpikeVectorPath(id, attrs);
    },

    getSpikeVectorPath: function(id, attrs){
      return '<polygon data-side="center" class="svg-empty-' + id + '" points="281.1,129.8 364,55.7 255.5,46.8 214,-59 172.5,46.8 64,55.4 146.8,129.7 121.1,241 212.9,181.1 213.9,181 306.5,241 " style="fill: transparent; stroke: ' + attrs.strokeColor + ';" />' +
        '<polygon data-side="left" class="svg-empty-' + id + '" points="281.1,129.8 364,55.7 255.5,46.8 214,-59 172.5,46.8 64,55.4 146.8,129.7 121.1,241 213.9,181.1 213.9,181 306.5,241 " style="stroke-opacity: 0;" />' +
          '<polygon data-side="right" class="svg-empty-' + id + '" points="364,55.7 255.5,46.8 214,-59 213.9,181 306.5,241 281.1,129.8 " style="stroke-opacity: 0;" />';
    },

    getRoundedVectorPath: function(id, attrs){
      var fullPoints = 'M520.9,336.5c-3.8-11.8-14.2-20.5-26.5-22.2l-140.9-20.5l-63-127.7 c-5.5-11.2-16.8-18.2-29.3-18.2c-12.5,0-23.8,7-29.3,18.2l-63,127.7L28,314.2C15.7,316,5.4,324.7,1.6,336.5S1,361.3,9.9,370 l102,99.4l-24,140.3c-2.1,12.3,2.9,24.6,13,32c5.7,4.2,12.4,6.2,19.2,6.2c5.2,0,10.5-1.2,15.2-3.8l126-66.3l126,66.2 c4.8,2.6,10,3.8,15.2,3.8c6.8,0,13.5-2.1,19.2-6.2c10.1-7.3,15.1-19.7,13-32l-24-140.3l102-99.4 C521.6,361.3,524.8,348.3,520.9,336.5z';

      return '<path data-side="center" class="svg-empty-' + id + '" d="' + fullPoints + '" style="stroke: ' + attrs.strokeColor + '; fill: transparent; " /><path data-side="right" class="svg-empty-' + id + '" d="' + fullPoints + '" style="stroke-opacity: 0;" /><path data-side="left" class="svg-empty-' + id + '" d="M121,648c-7.3,0-14.1-2.2-19.8-6.4c-10.4-7.6-15.6-20.3-13.4-33l24-139.9l-101.6-99 c-9.1-8.9-12.4-22.4-8.6-34.5c3.9-12.1,14.6-21.1,27.2-23l140.4-20.4L232,164.6c5.7-11.6,17.3-18.8,30.2-16.8c0.6,0,1,0.4,1,1 v430.1c0,0.4-0.2,0.7-0.5,0.9l-126,66.3C132,646.6,126.6,648,121,648z" style="stroke: ' + attrs.strokeColor + '; stroke-opacity: 0;" />';
    },

    getSvgDimensions: function(starShape){
      return (starShape === 'rounded') ? 'width="550px" height="500.2px" viewBox="0 146.8 550 500.2" style="enable-background:new 0 0 550 500.2;' : 'x="0px" y="0px" width="305px" height="305px" viewBox="60 -62 309 309" style="enable-background:new 64 -59 305 305;';
    },

    getLinearGradient: function(id, startColor, endColor, starShape){
      var height = (starShape === 'rounded') ? 500 : 250;
      return '<linearGradient id="' + id + '" gradientUnits="userSpaceOnUse" x1="0" y1="-50" x2="0" y2="' + height + '"><stop  offset="0" style="stop-color:' + startColor + '"/><stop  offset="1" style="stop-color:' + endColor + '"/> </linearGradient>';
    },

    executeCallback: function(rating, $el){
      var callback = this.settings.callback;
      callback(rating, $el);
    }

  };

  var publicMethods = {

    unload: function() {
      var _name = 'plugin_' + pluginName;
      var $el = $(this);
      var $starSet = $el.data(_name).$stars;
      $starSet.off();
      $el.removeData(_name).remove();
    },

    setRating: function(rating, round) {
      var _name = 'plugin_' + pluginName;
      var $el = $(this);
      var $plugin = $el.data(_name);
      if( rating > $plugin.settings.totalStars || rating < 0 ) { return; }
      if( round ){
        rating = Math.round(rating);
      }
      $plugin.applyRating(rating);
    },

    getRating: function() {
      var _name = 'plugin_' + pluginName;
      var $el = $(this);
      var $starSet = $el.data(_name);
      return $starSet._state.rating;
    },

    resize: function(newSize) {
      var _name = 'plugin_' + pluginName;
      var $el = $(this);
      var $starSet = $el.data(_name);
      var $stars = $starSet.$stars;

      if(newSize <= 1 || newSize > 200) {
        console.log('star size out of bounds');
        return;
      }

      $stars = Array.prototype.slice.call($stars);
      $stars.forEach(function(star){
        $(star).css({
          'width': newSize + 'px',
          'height': newSize + 'px'
        });
      });
    },

    setReadOnly: function(flag) {
      var _name = 'plugin_' + pluginName;
      var $el = $(this);
      var $plugin = $el.data(_name);
      if(flag === true){
        $plugin.$stars.off('mouseover mouseout click');
      } else {
        $plugin.settings.readOnly = false;
        $plugin.addListeners();
      }
    }

  };


  // Avoid Plugin.prototype conflicts
  $.extend(Plugin.prototype, methods);

  $.fn[ pluginName ] = function ( options ) {

    // if options is a public method
    if( !$.isPlainObject(options) ){
      if( publicMethods.hasOwnProperty(options) ){
        return publicMethods[options].apply(this, Array.prototype.slice.call(arguments, 1));
      } else {
        $.error('Method '+ options +' does not exist on ' + pluginName + '.js');
      }
    }

    return this.each(function() {
      // preventing against multiple instantiations
      if ( !$.data( this, 'plugin_' + pluginName ) ) {
        $.data( this, 'plugin_' + pluginName, new Plugin( this, options ) );
      }
    });
  };

})( jQuery, window, document );