123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /*!
- * jQuery Raty - A Star Rating Plugin - http://wbotelhos.com/raty
- * -------------------------------------------------------------------
- *
- * jQuery Raty is a plugin that generates a customizable star rating.
- *
- * Licensed under The MIT License
- *
- * @version 2.4.5
- * @since 2010.06.11
- * @author Washington Botelho
- * @documentation wbotelhos.com/raty
- * @twitter twitter.com/wbotelhos
- *
- * Usage:
- * -------------------------------------------------------------------
- * $('#star').raty();
- *
- * <div id="star"></div>
- *
- */
- ;(function($) {
- var methods = {
- init: function(settings) {
- return this.each(function() {
- var self = this,
- $this = $(self).empty();
-
- self.opt = $.extend(true, {}, $.fn.raty.defaults, settings);
- $this.data('settings', self.opt);
- self.opt.number = methods.between(self.opt.number, 0, 20);
- if (self.opt.path.substring(self.opt.path.length - 1, self.opt.path.length) != '/') {
- self.opt.path += '/';
- }
- if (typeof self.opt.score == 'function') {
- self.opt.score = self.opt.score.call(self);
- }
- if (self.opt.score) {
- self.opt.score = methods.between(self.opt.score, 0, self.opt.number);
- }
- for (var i = 1; i <= self.opt.number; i++) {
- $('<img />', {
- src : self.opt.path + ((!self.opt.score || self.opt.score < i) ? self.opt.starOff : self.opt.starOn),
- alt : i,
- title : (i <= self.opt.hints.length && self.opt.hints[i - 1] !== null) ? self.opt.hints[i - 1] : i
- }).appendTo(self);
- if (self.opt.space) {
- $this.append((i < self.opt.number) ? ' ' : '');
- }
- }
- self.stars = $this.children('img:not(".raty-cancel")');
- self.score = $('<input />', { type: 'hidden', name: self.opt.scoreName }).appendTo(self);
- if (self.opt.score && self.opt.score > 0) {
- self.score.val(self.opt.score);
- methods.roundStar.call(self, self.opt.score);
- }
- if (self.opt.iconRange) {
- methods.fill.call(self, self.opt.score);
- }
- methods.setTarget.call(self, self.opt.score, self.opt.targetKeep);
- var space = self.opt.space ? 4 : 0,
- width = self.opt.width || (self.opt.number * self.opt.size + self.opt.number * space);
- if (self.opt.cancel) {
- self.cancel = $('<img />', { src: self.opt.path + self.opt.cancelOff, alt: 'x', title: self.opt.cancelHint, 'class': 'raty-cancel' });
- if (self.opt.cancelPlace == 'left') {
- $this.prepend(' ').prepend(self.cancel);
- } else {
- $this.append(' ').append(self.cancel);
- }
- width += (self.opt.size + space);
- }
- if (self.opt.readOnly) {
- methods.fixHint.call(self);
- if (self.cancel) {
- self.cancel.hide();
- }
- } else {
- $this.css('cursor', 'pointer');
- methods.bindAction.call(self);
- }
- $this.css('width', width);
- });
- }, between: function(value, min, max) {
- return Math.min(Math.max(parseFloat(value), min), max);
- }, bindAction: function() {
- var self = this,
- $this = $(self);
- $this.mouseleave(function() {
- var score = self.score.val() || undefined;
- methods.initialize.call(self, score);
- methods.setTarget.call(self, score, self.opt.targetKeep);
- if (self.opt.mouseover) {
- self.opt.mouseover.call(self, score);
- }
- });
- var action = self.opt.half ? 'mousemove' : 'mouseover';
- if (self.opt.cancel) {
- self.cancel.mouseenter(function() {
- $(this).attr('src', self.opt.path + self.opt.cancelOn);
- self.stars.attr('src', self.opt.path + self.opt.starOff);
- methods.setTarget.call(self, null, true);
- if (self.opt.mouseover) {
- self.opt.mouseover.call(self, null);
- }
- }).mouseleave(function() {
- $(this).attr('src', self.opt.path + self.opt.cancelOff);
- if (self.opt.mouseover) {
- self.opt.mouseover.call(self, self.score.val() || null);
- }
- }).click(function(evt) {
- self.score.removeAttr('value');
- if (self.opt.click) {
- self.opt.click.call(self, null, evt);
- }
- });
- }
- self.stars.bind(action, function(evt) {
- var value = parseInt(this.alt, 10);
- if (self.opt.half) {
- var position = parseFloat((evt.pageX - $(this).offset().left) / self.opt.size),
- diff = (position > .5) ? 1 : .5;
- value = parseFloat(this.alt) - 1 + diff;
- methods.fill.call(self, value);
- if (self.opt.precision) {
- value = value - diff + position;
- }
- methods.showHalf.call(self, value);
- } else {
- methods.fill.call(self, value);
- }
- $this.data('score', value);
- methods.setTarget.call(self, value, true);
- if (self.opt.mouseover) {
- self.opt.mouseover.call(self, value, evt);
- }
- }).click(function(evt) {
- self.score.val((self.opt.half || self.opt.precision) ? $this.data('score') : this.alt);
- if (self.opt.click) {
- self.opt.click.call(self, self.score.val(), evt);
- }
- });
- }, cancel: function(isClick) {
- return $(this).each(function() {
- var self = this,
- $this = $(self);
- if ($this.data('readonly') === true) {
- return this;
- }
- if (isClick) {
- methods.click.call(self, null);
- } else {
- methods.score.call(self, null);
- }
- self.score.removeAttr('value');
- });
- }, click: function(score) {
- return $(this).each(function() {
- if ($(this).data('readonly') === true) {
- return this;
- }
- methods.initialize.call(this, score);
- if (this.opt.click) {
- this.opt.click.call(this, score);
- } else {
- methods.error.call(this, 'you must add the "click: function(score, evt) { }" callback.');
- }
- methods.setTarget.call(this, score, true);
- });
- }, error: function(message) {
- $(this).html(message);
- $.error(message);
- }, fill: function(score) {
- var self = this,
- number = self.stars.length,
- count = 0,
- $star ,
- star ,
- icon ;
- for (var i = 1; i <= number; i++) {
- $star = self.stars.eq(i - 1);
- if (self.opt.iconRange && self.opt.iconRange.length > count) {
- star = self.opt.iconRange[count];
- if (self.opt.single) {
- icon = (i == score) ? (star.on || self.opt.starOn) : (star.off || self.opt.starOff);
- } else {
- icon = (i <= score) ? (star.on || self.opt.starOn) : (star.off || self.opt.starOff);
- }
- if (i <= star.range) {
- $star.attr('src', self.opt.path + icon);
- }
- if (i == star.range) {
- count++;
- }
- } else {
- if (self.opt.single) {
- icon = (i == score) ? self.opt.starOn : self.opt.starOff;
- } else {
- icon = (i <= score) ? self.opt.starOn : self.opt.starOff;
- }
- $star.attr('src', self.opt.path + icon);
- }
- }
- }, fixHint: function() {
- var $this = $(this),
- score = parseInt(this.score.val(), 10),
- hint = this.opt.noRatedMsg;
- if (!isNaN(score) && score > 0) {
- hint = (score <= this.opt.hints.length && this.opt.hints[score - 1] !== null) ? this.opt.hints[score - 1] : score;
- }
- $this.data('readonly', true).css('cursor', 'default').attr('title', hint);
- this.score.attr('readonly', 'readonly');
- this.stars.attr('title', hint);
- }, getScore: function() {
- var score = [],
- value ;
- $(this).each(function() {
- value = this.score.val();
- score.push(value ? parseFloat(value) : undefined);
- });
- return (score.length > 1) ? score : score[0];
- }, readOnly: function(isReadOnly) {
- return this.each(function() {
- var $this = $(this);
- if ($this.data('readonly') === isReadOnly) {
- return this;
- }
- if (this.cancel) {
- if (isReadOnly) {
- this.cancel.hide();
- } else {
- this.cancel.show();
- }
- }
- if (isReadOnly) {
- $this.unbind();
- $this.children('img').unbind();
- methods.fixHint.call(this);
- } else {
- methods.bindAction.call(this);
- methods.unfixHint.call(this);
- }
- $this.data('readonly', isReadOnly);
- });
- }, reload: function() {
- return methods.set.call(this, {});
- }, roundStar: function(score) {
- var diff = (score - Math.floor(score)).toFixed(2);
- if (diff > this.opt.round.down) {
- var icon = this.opt.starOn; // Full up: [x.76 .. x.99]
- if (diff < this.opt.round.up && this.opt.halfShow) { // Half: [x.26 .. x.75]
- icon = this.opt.starHalf;
- } else if (diff < this.opt.round.full) { // Full down: [x.00 .. x.5]
- icon = this.opt.starOff;
- }
- this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + icon);
- } // Full down: [x.00 .. x.25]
- }, score: function() {
- return arguments.length ? methods.setScore.apply(this, arguments) : methods.getScore.call(this);
- }, set: function(settings) {
- this.each(function() {
- var $this = $(this),
- actual = $this.data('settings'),
- clone = $this.clone().removeAttr('style').insertBefore($this);
- $this.remove();
- clone.raty($.extend(actual, settings));
- });
- return $(this.selector);
- }, setScore: function(score) {
- return $(this).each(function() {
- if ($(this).data('readonly') === true) {
- return this;
- }
- methods.initialize.call(this, score);
- methods.setTarget.call(this, score, true);
- });
- }, setTarget: function(value, isKeep) {
- if (this.opt.target) {
- var $target = $(this.opt.target);
- if ($target.length == 0) {
- methods.error.call(this, 'target selector invalid or missing!');
- }
- var score = value;
- if (!isKeep || score === undefined) {
- score = this.opt.targetText;
- } else {
- if (this.opt.targetType == 'hint') {
- score = (score === null && this.opt.cancel)
- ? this.opt.cancelHint
- : this.opt.hints[Math.ceil(score - 1)];
- } else {
- score = this.opt.precision
- ? parseFloat(score).toFixed(1)
- : parseInt(score, 10);
- }
- }
- if (this.opt.targetFormat.indexOf('{score}') < 0) {
- methods.error.call(this, 'template "{score}" missing!');
- }
- if (value !== null) {
- score = this.opt.targetFormat.toString().replace('{score}', score);
- }
- if ($target.is(':input')) {
- $target.val(score);
- } else {
- $target.html(score);
- }
- }
- }, showHalf: function(score) {
- var diff = (score - Math.floor(score)).toFixed(1);
- if (diff > 0 && diff < .6) {
- this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + this.opt.starHalf);
- }
- }, initialize: function(score) {
- score = !score ? 0 : methods.between(score, 0, this.opt.number);
- methods.fill.call(this, score);
- if (score > 0) {
- if (this.opt.halfShow) {
- methods.roundStar.call(this, score);
- }
- this.score.val(score);
- }
- }, unfixHint: function() {
- for (var i = 0; i < this.opt.number; i++) {
- this.stars.eq(i).attr('title', (i < this.opt.hints.length && this.opt.hints[i] !== null) ? this.opt.hints[i] : i);
- }
- $(this).data('readonly', false).css('cursor', 'pointer').removeAttr('title');
- this.score.attr('readonly', 'readonly');
- }
- };
- $.fn.raty = function(method) {
- if (methods[method]) {
- return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
- } else if (typeof method === 'object' || !method) {
- return methods.init.apply(this, arguments);
- } else {
- $.error('Method ' + method + ' does not exist!');
- }
- };
- $.fn.raty.defaults = {
- cancel : false,
- cancelHint : 'cancel this rating!',
- cancelOff : 'cancel-off.png',
- cancelOn : 'cancel-on.png',
- cancelPlace : 'left',
- click : undefined,
- half : false,
- halfShow : true,
- hints : ['1', '2', '3', '4', '5' ],
- iconRange : undefined,
- mouseover : undefined,
- noRatedMsg : 'not rated yet',
- number : 5,
- path : 'images/',
- precision : false,
- round : { down: .25, full: .6, up: .76 },
- readOnly : false,
- score : undefined,
- scoreName : 'score',
- single : false,
- size : 16,
- space : true,
- starHalf : 'star-half.png',
- starOff : 'star-off.png',
- starOn : 'star-on.png',
- target : undefined,
- targetFormat : '{score}',
- targetKeep : false,
- targetText : '',
- targetType : 'hint',
- width : undefined
- };
- })(jQuery);
|