/*! * @copyright © Kartik Visweswaran, Krajee.com, 2014 * @version 2.5.0 * * A simple yet powerful JQuery star rating plugin that allows rendering * fractional star ratings and supports Right to Left (RTL) input. * * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ (function ($) { var DEFAULT_MIN = 0; var DEFAULT_MAX = 5; var DEFAULT_STEP = 0.5; var isEmpty = function (value, trim) { return typeof value === 'undefined' || value === null || value === undefined || value == [] || value === '' || trim && $.trim(value) === ''; }; var validateAttr = function ($input, vattr, options) { var chk = isEmpty($input.data(vattr)) ? $input.attr(vattr) : $input.data(vattr); if (chk) { return chk; } return options[vattr]; }; var getDecimalPlaces = function (num) { var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); if (!match) { return 0; } return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); }; var applyPrecision = function (val, precision) { return parseFloat(val.toFixed(precision)); }; // Rating public class definition var Rating = function (element, options) { this.$element = $(element); this.init(options); }; Rating.prototype = { constructor: Rating, _parseAttr: function (vattr, options) { var self = this, $input = self.$element; if ($input.attr('type') === 'range' || $input.attr('type') === 'number') { var val = validateAttr($input, vattr, options); var chk = DEFAULT_STEP; if (vattr === 'min') { chk = DEFAULT_MIN; } else if (vattr === 'max') { chk = DEFAULT_MAX; } else if (vattr === 'step') { chk = DEFAULT_STEP; } var final = isEmpty(val) ? chk : val; return parseFloat(final); } return parseFloat(options[vattr]); }, /** * Listens to events */ listen: function () { var self = this; self.$rating.on("click", function (e) { if (!self.inactive) { w = e.pageX - self.$rating.offset().left; self.setStars(w); self.$element.trigger('change'); self.$element.trigger('rating.change', [self.$element.val(), self.$caption.html()]); } }); self.$clear.on("click", function (e) { if (!self.inactive) { self.clear(); } }); $(self.$element[0].form).on("reset", function (e) { if (!self.inactive) { self.reset(); } }); }, initSlider: function (options) { var self = this; if (isEmpty(self.$element.val())) { self.$element.val(0); } self.initialValue = self.$element.val(); self.min = (typeof options.min !== 'undefined') ? options.min : self._parseAttr('min', options); self.max = (typeof options.max !== 'undefined') ? options.max : self._parseAttr('max', options); self.step = (typeof options.step !== 'undefined') ? options.step : self._parseAttr('step', options); if (isNaN(self.min) || isEmpty(self.min)) { self.min = DEFAULT_MIN; } if (isNaN(self.max) || isEmpty(self.max)) { self.max = DEFAULT_MAX; } if (isNaN(self.step) || isEmpty(self.step) || self.step == 0) { self.step = DEFAULT_STEP; } self.diff = self.max - self.min; }, /** * Initializes the plugin */ init: function (options) { var self = this; self.options = options; self.initSlider(options); self.checkDisabled(); $element = self.$element; self.containerClass = options.containerClass; self.glyphicon = options.glyphicon; var defaultStar = (self.glyphicon) ? '\ue006' : '\u2605'; self.symbol = isEmpty(options.symbol) ? defaultStar : options.symbol; self.rtl = options.rtl || self.$element.attr('dir'); if (self.rtl) { self.$element.attr('dir', 'rtl'); } self.showClear = options.showClear; self.showCaption = options.showCaption; self.size = options.size; self.stars = options.stars; self.defaultCaption = options.defaultCaption; self.starCaptions = options.starCaptions; self.starCaptionClasses = options.starCaptionClasses; self.clearButton = options.clearButton; self.clearButtonTitle = options.clearButtonTitle; self.clearButtonBaseClass = !isEmpty(options.clearButtonBaseClass) ? options.clearButtonBaseClass : 'clear-rating'; self.clearButtonActiveClass = !isEmpty(options.clearButtonActiveClass) ? options.clearButtonActiveClass : 'clear-rating-active'; self.clearCaption = options.clearCaption; self.clearCaptionClass = options.clearCaptionClass; self.clearValue = options.clearValue; self.$element.removeClass('form-control').addClass('form-control'); self.$clearElement = isEmpty(options.clearElement) ? null : $(options.clearElement); self.$captionElement = isEmpty(options.captionElement) ? null : $(options.captionElement); if (typeof self.$rating == 'undefined' && typeof self.$container == 'undefined') { self.$rating = $(document.createElement("div")).html('
'); self.$container = $(document.createElement("div")); self.$container.before(self.$rating); self.$container.append(self.$rating); self.$element.before(self.$container).appendTo(self.$rating); } self.$stars = self.$rating.find('.rating-stars'); self.generateRating(); self.$clear = !isEmpty(self.$clearElement) ? self.$clearElement : self.$container.find('.' + self.clearButtonBaseClass); self.$caption = !isEmpty(self.$captionElement) ? self.$captionElement : self.$container.find(".caption"); self.setStars(); self.$element.hide(); self.listen(); if (self.showClear) { self.$clear.attr({"class": self.getClearClass()}); } }, checkDisabled: function () { var self = this; self.disabled = validateAttr(self.$element, 'disabled', self.options); self.readonly = validateAttr(self.$element, 'readonly', self.options); self.inactive = (self.disabled || self.readonly); }, getClearClass: function () { return this.clearButtonBaseClass + ' ' + ((this.inactive) ? '' : this.clearButtonActiveClass); }, generateRating: function () { var self = this, clear = self.renderClear(), caption = self.renderCaption(), css = (self.rtl) ? 'rating-container-rtl' : 'rating-container', stars = self.getStars(); css += (self.glyphicon) ? ((self.symbol == '\ue006') ? ' rating-gly-star' : ' rating-gly') : ' rating-uni'; self.$rating.attr('class', css); self.$rating.attr('data-content', stars); self.$stars.attr('data-content', stars); var css = self.rtl ? 'star-rating-rtl' : 'star-rating'; self.$container.attr('class', css + ' rating-' + self.size); if (self.inactive) { self.$container.removeClass('rating-active').addClass('rating-disabled'); } else { self.$container.removeClass('rating-disabled').addClass('rating-active'); } if (typeof self.$caption == 'undefined' && typeof self.$clear == 'undefined') { if (self.rtl) { self.$container.prepend(caption).append(clear); } else { self.$container.prepend(clear).append(caption); } } if (!isEmpty(self.containerClass)) { self.$container.removeClass(self.containerClass).addClass(self.containerClass); } }, getStars: function () { var self = this, numStars = self.stars, stars = ''; for (var i = 1; i <= numStars; i++) { stars += self.symbol; } return stars; }, renderClear: function () { var self = this; if (!self.showClear) { return ''; } var css = self.getClearClass(); if (!isEmpty(self.$clearElement)) { self.$clearElement.removeClass(css).addClass(css).attr({"title": self.clearButtonTitle}); self.$clearElement.html(self.clearButton); return ''; } return '