jQuery(document).ready(function() { $.fn.likeButton = function(settings) { settings = $.extend({ /** * URL to PHP script * @type {String} */ url: '/LikeButton/', /** * Disable default button counter * @type {Boolean} */ disableCounter: false, /** * Class name of element which will be updated with number of likes * @type {String} */ customCounter: 'btn-like-custom-counter', /** * Function called before request * @param {DOM Element} btn */ before: function(btn) {}, /** * Function called after each request * @param {jQuery} btn * @param {Object} response */ after: function(btn, response) {} }, settings); var _ = { elements: this.selector, IDs: null, init: function() { _.getIDs(_.elements); // Load number of likes for each button if (_.IDs.length) _.update(); _.bindActions(); }, randomID: function() { var a, b = b || 16; return Array(a || 8).join(0).replace(/0/g, function() { return (0 | Math.random() * b).toString(b) }); }, getIDs: function(selector) { _.IDs = $.map($(selector), function(el) { return $(el).attr('data-item-id'); }); }, counter: function(btn) { if (!btn) return; var counter = $('.btn-like-counter[data-counter-id=' + btn.attr('data-counter-id') + ']').add('.' + settings.customCounter + '[data-counter-id=' + btn.attr('data-counter-id') + ']'); return { add: function() { var counterID = _.randomID(), position, type, url, title, counterDisabled; $.each(btn, function() { var btn = $(this); attrs = { 'data-counter-id': counterID }; position = btn.data('count') === 'vertical' ? 'before' : 'after'; type = 'btn-like-counter--' + (btn.data('count') || 'horizontal'); if (url = btn.attr('data-url')) attrs.href = url; if (title = btn.attr('data-title')) attrs.title = title; if (!btn.attr('data-counter-id')) { btn.addClass('btn-like--' + (btn.data('count') || 'horizontal')) btn.attr('data-counter-id', counterID); $('.' + settings.customCounter).filter(function() { return $(this).attr('data-item-id') == btn.attr('data-item-id'); }).attr('data-counter-id', counterID); btn.wrap($('
').addClass('btn-like-wrap')); counterDisabled = btn.data('disable-counter') === false ? false : btn.data('disable-counter') === true ? true : settings.disableCounter; if (!counterDisabled) { btn[position]( $('<' + (url ? 'a' : 'span') + '/>').addClass('btn-like-counter ' + type).attr(attrs) ); } } }); return _.counter(btn); }, get: function() { return counter; }, update: function(value) { counter.attr('data-value', value).text(value); return _.counter(btn); } } }, bindActions: function() { $('body').delegate(_.elements, 'click', function() { var btn = $('.btn-like[data-counter-id=' + $(this).data('counter-id') + ']'); // Add loader _.counter(btn).update(''); _.counter(btn).get().addClass('is-loading'); settings.before($(this)); $.post(settings.url, {'lb-item-id': btn.attr('data-item-id')}, function (item) { // Set counter and remove loader _.counter(btn).update(item.count).get().removeClass('is-loading'); // Set active class btn[item.isLiked ? 'addClass' : 'removeClass']('active'); settings.after(this, item); }); /** * Additional method to update new buttons added to DOM */ }).delegate(_.elements, 'update', function() { _.getIDs(this.selector); _.update(_.IDs); }); }, update: function() { $.post(settings.url, {'lb-item-ids': _.IDs}, function (items) { $.each(items, function() { var btn = $(_.elements + '[data-item-id=' + this.id + ']'); // Add counter and update value _.counter(btn).add().update(this.count); // Set active class btn[this.isLiked ? 'addClass' : 'removeClass']('active'); settings.after(btn, this); }); }); } }; _.init(); return this; }; });