Last active
September 11, 2018 16:11
-
-
Save klarstil/5642487 to your computer and use it in GitHub Desktop.
Simple star rating
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(function ( $, window, document, undefined ) { | |
"use strict"; | |
var pluginName = 'starRating', _lastActive = -1, | |
defaults = { | |
baseCls: 'star-rating', | |
activeCls: 'is-active', | |
hoverCls: 'is-hover', | |
nonInteractiveCls: 'is-non-interactive' | |
}; | |
/** | |
* Plugin constructor which merges the default settings | |
* with the user configuration and sets up the DOM bridge. | |
* | |
* @param { HTMLElement } element | |
* @param { Object } options | |
* @returms { Void } | |
* @constructor | |
*/ | |
function Plugin( element, options ) { | |
this.element = element; | |
this.$el = $(element); | |
this.options = $.extend( {}, defaults, options); | |
this._isInteractive = this.$el.attr('data-interactive'); | |
this._defaults = defaults; | |
this._name = pluginName; | |
this.init(); | |
} | |
/** | |
* Initialized the plugin, sets up the template | |
* and marks the selected as active. | |
* | |
* @returns { Void } | |
*/ | |
Plugin.prototype.init = function () { | |
var me = this, | |
selected = me.$el.find(':selected'); | |
me.$tpl = me.createTemplate(); | |
if(me._isInteractive) { | |
me.bindEvents(); | |
} else { | |
me.$tpl.addClass(me.options.nonInteractiveCls); | |
} | |
me.$el.replaceWith(me.$tpl); | |
if(selected && selected.val()) { | |
if(me._isInteractive) { | |
me.$tpl.find('a:nth-child(' + selected.val() + ')').trigger('click.' + pluginName); | |
} else { | |
me.onSetActive(selected.val()); | |
} | |
} | |
}; | |
/** | |
* Binds the event handlers to the elements. | |
* | |
* @returns { Void } | |
*/ | |
Plugin.prototype.bindEvents = function() { | |
var me = this; | |
me.$tpl.delegate('a', 'click.' + pluginName, function(event) { | |
event.preventDefault(); | |
_lastActive = ~~(1 * $(this).attr('data-star-rating-value')) | |
me.onSetActive(_lastActive); | |
}); | |
me.$tpl.on('hover', function() { | |
me.$tpl.toggleClass(me.options.hoverCls); | |
}); | |
me.$tpl.delegate('a', 'mouseenter.' + pluginName, function(event) { | |
event.preventDefault(); | |
me.onSetActive(~~(1 * $(this).attr('data-star-rating-value'))); | |
}); | |
me.$tpl.on('mouseleave.' + pluginName, function(event) { | |
event.preventDefault(); | |
if(_lastActive > 0) { | |
me.onSetActive(_lastActive); | |
} else { | |
me.onClearSelection(event) | |
} | |
}); | |
}; | |
/** | |
* Event listener which sets the incoming position active. | |
* | |
* @event click.starRating | |
* @param { Integer } pos | |
* @returns { Boolean } | |
*/ | |
Plugin.prototype.onSetActive = function(pos) { | |
var me = this, | |
tpl = me.$tpl, | |
elements = tpl.find('a').removeClass(me.options.activeCls), | |
i = 0; | |
for(; i < pos; i++) { | |
$(elements[i]).addClass(me.options.activeCls); | |
} | |
return true; | |
}; | |
/** | |
* Event listener which clears any selection | |
* | |
* @param {jQuery.Event } event | |
* @returns { Boolean } | |
*/ | |
Plugin.prototype.onClearSelection = function(event) { | |
event.preventDefault(); | |
var me = this, | |
tpl = me.$tpl; | |
tpl.find('a').removeClass(me.options.activeCls); | |
_lastActive = -1; | |
return true; | |
}; | |
/** | |
* Creates the template for the plugin. | |
* | |
* @returns { jQuery } | |
*/ | |
Plugin.prototype.createTemplate = function() { | |
var me = this, | |
options = me.$el.find('option'), | |
len = options.length, i = 0, option, clearEl, val, | |
container = $('<div>', { 'class': me.options.baseCls + '-container' }); | |
for(; i < len; i++) { | |
option = $(options[i]); | |
val = option.val() | |
$('<a>', { | |
'class': me.options.baseCls + '-option ' + me.options.baseCls + '-option-' + val, | |
'href': '#rate-' + val, | |
'data-star-rating-value': val | |
}).appendTo(container); | |
} | |
if(me._isInteractive) { | |
$('<span>', { 'class': me.options.baseCls + '-clear' }) | |
.appendTo(container) | |
.on('click', $.proxy(me.onClearSelection, me)); | |
} | |
return container; | |
}; | |
/** Lightweight plugin starter */ | |
$.fn[pluginName] = function ( options ) { | |
return this.each(function () { | |
if (!$.data(this, 'plugin_' + pluginName)) { | |
$.data(this, 'plugin_' + pluginName, | |
new Plugin( this, options )); | |
} | |
}); | |
} | |
$(function() { | |
$('[data-plugin=star-rating]').starRating(); | |
}); | |
})( jQuery, window, document ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment