| 1 | /*
|
|---|
| 2 | ### jQuery Star Rating Plugin v3.13 - 2009-03-26 ###
|
|---|
| 3 | * Home: http://www.fyneworks.com/jquery/star-rating/
|
|---|
| 4 | * Code: http://code.google.com/p/jquery-star-rating-plugin/
|
|---|
| 5 | *
|
|---|
| 6 | * Dual licensed under the MIT and GPL licenses:
|
|---|
| 7 | * http://www.opensource.org/licenses/mit-license.php
|
|---|
| 8 | * http://www.gnu.org/licenses/gpl.html
|
|---|
| 9 | ###
|
|---|
| 10 | */
|
|---|
| 11 |
|
|---|
| 12 | /*# AVOID COLLISIONS #*/
|
|---|
| 13 | ;if(window.jQuery) (function($){
|
|---|
| 14 | /*# AVOID COLLISIONS #*/
|
|---|
| 15 |
|
|---|
| 16 | // IE6 Background Image Fix
|
|---|
| 17 | if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { };
|
|---|
| 18 | // Thanks to http://www.visualjquery.com/rating/rating_redux.html
|
|---|
| 19 |
|
|---|
| 20 | // plugin initialization
|
|---|
| 21 | $.fn.rating = function(options){
|
|---|
| 22 | if(this.length==0) return this; // quick fail
|
|---|
| 23 |
|
|---|
| 24 | // Handle API methods
|
|---|
| 25 | if(typeof arguments[0]=='string'){
|
|---|
| 26 | // Perform API methods on individual elements
|
|---|
| 27 | if(this.length>1){
|
|---|
| 28 | var args = arguments;
|
|---|
| 29 | return this.each(function(){
|
|---|
| 30 | $.fn.rating.apply($(this), args);
|
|---|
| 31 | });
|
|---|
| 32 | };
|
|---|
| 33 | // Invoke API method handler
|
|---|
| 34 | $.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
|
|---|
| 35 | // Quick exit...
|
|---|
| 36 | return this;
|
|---|
| 37 | };
|
|---|
| 38 |
|
|---|
| 39 | // Initialize options for this call
|
|---|
| 40 | var options = $.extend(
|
|---|
| 41 | {}/* new object */,
|
|---|
| 42 | $.fn.rating.options/* default options */,
|
|---|
| 43 | options || {} /* just-in-time options */
|
|---|
| 44 | );
|
|---|
| 45 |
|
|---|
| 46 | // Allow multiple controls with the same name by making each call unique
|
|---|
| 47 | $.fn.rating.calls++;
|
|---|
| 48 |
|
|---|
| 49 | // loop through each matched element
|
|---|
| 50 | this
|
|---|
| 51 | .not('.star-rating-applied')
|
|---|
| 52 | .addClass('star-rating-applied')
|
|---|
| 53 | .each(function(){
|
|---|
| 54 |
|
|---|
| 55 | // Load control parameters / find context / etc
|
|---|
| 56 | var control, input = $(this);
|
|---|
| 57 | var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,'');
|
|---|
| 58 | var context = $(this.form || document.body);
|
|---|
| 59 |
|
|---|
| 60 | // FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
|
|---|
| 61 | var raters = context.data('rating');
|
|---|
| 62 | if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls };
|
|---|
| 63 | var rater = raters[eid];
|
|---|
| 64 |
|
|---|
| 65 | // if rater is available, verify that the control still exists
|
|---|
| 66 | if(rater) control = rater.data('rating');
|
|---|
| 67 |
|
|---|
| 68 | if(rater && control)//{// save a byte!
|
|---|
| 69 | // add star to control if rater is available and the same control still exists
|
|---|
| 70 | control.count++;
|
|---|
| 71 |
|
|---|
| 72 | //}// save a byte!
|
|---|
| 73 | else{
|
|---|
| 74 | // create new control if first star or control element was removed/replaced
|
|---|
| 75 |
|
|---|
| 76 | // Initialize options for this raters
|
|---|
| 77 | control = $.extend(
|
|---|
| 78 | {}/* new object */,
|
|---|
| 79 | options || {} /* current call options */,
|
|---|
| 80 | ($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */
|
|---|
| 81 | { count:0, stars: [], inputs: [] }
|
|---|
| 82 | );
|
|---|
| 83 |
|
|---|
| 84 | // increment number of rating controls
|
|---|
| 85 | control.serial = raters.count++;
|
|---|
| 86 |
|
|---|
| 87 | // create rating element
|
|---|
| 88 | rater = $('<span class="star-rating-control"/>');
|
|---|
| 89 | input.before(rater);
|
|---|
| 90 |
|
|---|
| 91 | // Mark element for initialization (once all stars are ready)
|
|---|
| 92 | rater.addClass('rating-to-be-drawn');
|
|---|
| 93 |
|
|---|
| 94 | // Accept readOnly setting from 'disabled' property
|
|---|
| 95 | if(input.attr('disabled')) control.readOnly = true;
|
|---|
| 96 |
|
|---|
| 97 | // Create 'cancel' button
|
|---|
| 98 | rater.append(
|
|---|
| 99 | control.cancel = $('<div class="rating-cancel"><a title="' + control.cancel + '">' + control.cancelValue + '</a></div>')
|
|---|
| 100 | .mouseover(function(){
|
|---|
| 101 | $(this).rating('drain');
|
|---|
| 102 | $(this).addClass('star-rating-hover');
|
|---|
| 103 | //$(this).rating('focus');
|
|---|
| 104 | })
|
|---|
| 105 | .mouseout(function(){
|
|---|
| 106 | $(this).rating('draw');
|
|---|
| 107 | $(this).removeClass('star-rating-hover');
|
|---|
| 108 | //$(this).rating('blur');
|
|---|
| 109 | })
|
|---|
| 110 | .click(function(){
|
|---|
| 111 | $(this).rating('select');
|
|---|
| 112 | })
|
|---|
| 113 | .data('rating', control)
|
|---|
| 114 | );
|
|---|
| 115 |
|
|---|
| 116 | }; // first element of group
|
|---|
| 117 |
|
|---|
| 118 | // insert rating star
|
|---|
| 119 | var star = $('<div class="star-rating rater-'+ control.serial +'"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
|
|---|
| 120 | rater.append(star);
|
|---|
| 121 |
|
|---|
| 122 | // inherit attributes from input element
|
|---|
| 123 | if(this.id) star.attr('id', this.id);
|
|---|
| 124 | if(this.className) star.addClass(this.className);
|
|---|
| 125 |
|
|---|
| 126 | // Half-stars?
|
|---|
| 127 | if(control.half) control.split = 2;
|
|---|
| 128 |
|
|---|
| 129 | // Prepare division control
|
|---|
| 130 | if(typeof control.split=='number' && control.split>0){
|
|---|
| 131 | var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
|
|---|
| 132 | var spi = (control.count % control.split), spw = Math.floor(stw/control.split);
|
|---|
| 133 | star
|
|---|
| 134 | // restrict star's width and hide overflow (already in CSS)
|
|---|
| 135 | .width(spw)
|
|---|
| 136 | // move the star left by using a negative margin
|
|---|
| 137 | // this is work-around to IE's stupid box model (position:relative doesn't work)
|
|---|
| 138 | .find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' })
|
|---|
| 139 | };
|
|---|
| 140 |
|
|---|
| 141 | // readOnly?
|
|---|
| 142 | if(control.readOnly)//{ //save a byte!
|
|---|
| 143 | // Mark star as readOnly so user can customize display
|
|---|
| 144 | star.addClass('star-rating-readonly');
|
|---|
| 145 | //} //save a byte!
|
|---|
| 146 | else//{ //save a byte!
|
|---|
| 147 | // Enable hover css effects
|
|---|
| 148 | star.addClass('star-rating-live')
|
|---|
| 149 | // Attach mouse events
|
|---|
| 150 | .mouseover(function(){
|
|---|
| 151 | $(this).rating('fill');
|
|---|
| 152 | $(this).rating('focus');
|
|---|
| 153 | })
|
|---|
| 154 | .mouseout(function(){
|
|---|
| 155 | $(this).rating('draw');
|
|---|
| 156 | $(this).rating('blur');
|
|---|
| 157 | })
|
|---|
| 158 | .click(function(){
|
|---|
| 159 | $(this).rating('select');
|
|---|
| 160 | })
|
|---|
| 161 | ;
|
|---|
| 162 | //}; //save a byte!
|
|---|
| 163 |
|
|---|
| 164 | // set current selection
|
|---|
| 165 | if(this.checked) control.current = star;
|
|---|
| 166 |
|
|---|
| 167 | // hide input element
|
|---|
| 168 | input.hide();
|
|---|
| 169 |
|
|---|
| 170 | // backward compatibility, form element to plugin
|
|---|
| 171 | input.change(function(){
|
|---|
| 172 | $(this).rating('select');
|
|---|
| 173 | });
|
|---|
| 174 |
|
|---|
| 175 | // attach reference to star to input element and vice-versa
|
|---|
| 176 | star.data('rating.input', input.data('rating.star', star));
|
|---|
| 177 |
|
|---|
| 178 | // store control information in form (or body when form not available)
|
|---|
| 179 | control.stars[control.stars.length] = star[0];
|
|---|
| 180 | control.inputs[control.inputs.length] = input[0];
|
|---|
| 181 | control.rater = raters[eid] = rater;
|
|---|
| 182 | control.context = context;
|
|---|
| 183 |
|
|---|
| 184 | input.data('rating', control);
|
|---|
| 185 | rater.data('rating', control);
|
|---|
| 186 | star.data('rating', control);
|
|---|
| 187 | context.data('rating', raters);
|
|---|
| 188 | }); // each element
|
|---|
| 189 |
|
|---|
| 190 | // Initialize ratings (first draw)
|
|---|
| 191 | $('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');
|
|---|
| 192 |
|
|---|
| 193 | return this; // don't break the chain...
|
|---|
| 194 | };
|
|---|
| 195 |
|
|---|
| 196 | /*--------------------------------------------------------*/
|
|---|
| 197 |
|
|---|
| 198 | /*
|
|---|
| 199 | ### Core functionality and API ###
|
|---|
| 200 | */
|
|---|
| 201 | $.extend($.fn.rating, {
|
|---|
| 202 | // Used to append a unique serial number to internal control ID
|
|---|
| 203 | // each time the plugin is invoked so same name controls can co-exist
|
|---|
| 204 | calls: 0,
|
|---|
| 205 |
|
|---|
| 206 | focus: function(){
|
|---|
| 207 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 208 | if(!control.focus) return this; // quick fail if not required
|
|---|
| 209 | // find data for event
|
|---|
| 210 | var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
|
|---|
| 211 | // focus handler, as requested by focusdigital.co.uk
|
|---|
| 212 | if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
|
|---|
| 213 | }, // $.fn.rating.focus
|
|---|
| 214 |
|
|---|
| 215 | blur: function(){
|
|---|
| 216 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 217 | if(!control.blur) return this; // quick fail if not required
|
|---|
| 218 | // find data for event
|
|---|
| 219 | var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
|
|---|
| 220 | // blur handler, as requested by focusdigital.co.uk
|
|---|
| 221 | if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
|
|---|
| 222 | }, // $.fn.rating.blur
|
|---|
| 223 |
|
|---|
| 224 | fill: function(){ // fill to the current mouse position.
|
|---|
| 225 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 226 | // do not execute when control is in read-only mode
|
|---|
| 227 | if(control.readOnly) return;
|
|---|
| 228 | // Reset all stars and highlight them up to this element
|
|---|
| 229 | this.rating('drain');
|
|---|
| 230 | this.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-hover');
|
|---|
| 231 | },// $.fn.rating.fill
|
|---|
| 232 |
|
|---|
| 233 | drain: function() { // drain all the stars.
|
|---|
| 234 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 235 | // do not execute when control is in read-only mode
|
|---|
| 236 | if(control.readOnly) return;
|
|---|
| 237 | // Reset all stars
|
|---|
| 238 | control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
|
|---|
| 239 | },// $.fn.rating.drain
|
|---|
| 240 |
|
|---|
| 241 | draw: function(){ // set value and stars to reflect current selection
|
|---|
| 242 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 243 | // Clear all stars
|
|---|
| 244 | this.rating('drain');
|
|---|
| 245 | // Set control value
|
|---|
| 246 | if(control.current){
|
|---|
| 247 | control.current.data('rating.input').attr('checked','checked');
|
|---|
| 248 | control.current.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-on');
|
|---|
| 249 | }
|
|---|
| 250 | else
|
|---|
| 251 | $(control.inputs).removeAttr('checked');
|
|---|
| 252 | // Show/hide 'cancel' button
|
|---|
| 253 | control.cancel[control.readOnly || control.required?'hide':'show']();
|
|---|
| 254 | // Add/remove read-only classes to remove hand pointer
|
|---|
| 255 | this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly');
|
|---|
| 256 | },// $.fn.rating.draw
|
|---|
| 257 |
|
|---|
| 258 |
|
|---|
| 259 |
|
|---|
| 260 |
|
|---|
| 261 |
|
|---|
| 262 | select: function(value,wantCallBack){ // select a value
|
|---|
| 263 |
|
|---|
| 264 | // ***** MODIFICATION *****
|
|---|
| 265 | // Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
|
|---|
| 266 | //
|
|---|
| 267 | // ***** LIST OF MODIFICATION *****
|
|---|
| 268 | // ***** added Parameter wantCallBack : false if you don't want a callback. true or undefined if you want postback to be performed at the end of this method'
|
|---|
| 269 | // ***** recursive calls to this method were like : ... .rating('select') it's now like .rating('select',undefined,wantCallBack); (parameters are set.)
|
|---|
| 270 | // ***** line which is calling callback
|
|---|
| 271 | // ***** /LIST OF MODIFICATION *****
|
|---|
| 272 |
|
|---|
| 273 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 274 | // do not execute when control is in read-only mode
|
|---|
| 275 | if(control.readOnly) return;
|
|---|
| 276 | // clear selection
|
|---|
| 277 | control.current = null;
|
|---|
| 278 | // programmatically (based on user input)
|
|---|
| 279 | if(typeof value!='undefined'){
|
|---|
| 280 | // select by index (0 based)
|
|---|
| 281 | if(typeof value=='number')
|
|---|
| 282 | return $(control.stars[value]).rating('select',undefined,wantCallBack);
|
|---|
| 283 | // select by literal value (must be passed as a string
|
|---|
| 284 | if(typeof value=='string')
|
|---|
| 285 | //return
|
|---|
| 286 | $.each(control.stars, function(){
|
|---|
| 287 | if($(this).data('rating.input').val()==value) $(this).rating('select',undefined,wantCallBack);
|
|---|
| 288 | });
|
|---|
| 289 | }
|
|---|
| 290 | else
|
|---|
| 291 | control.current = this[0].tagName=='INPUT' ?
|
|---|
| 292 | this.data('rating.star') :
|
|---|
| 293 | (this.is('.rater-'+ control.serial) ? this : null);
|
|---|
| 294 |
|
|---|
| 295 | // Update rating control state
|
|---|
| 296 | this.data('rating', control);
|
|---|
| 297 | // Update display
|
|---|
| 298 | this.rating('draw');
|
|---|
| 299 | // find data for event
|
|---|
| 300 | var input = $( control.current ? control.current.data('rating.input') : null );
|
|---|
| 301 | // click callback, as requested here: http://plugins.jquery.com/node/1655
|
|---|
| 302 |
|
|---|
| 303 | // **** MODIFICATION *****
|
|---|
| 304 | // Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
|
|---|
| 305 | //
|
|---|
| 306 | //old line doing the callback :
|
|---|
| 307 | //if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
|
|---|
| 308 | //
|
|---|
| 309 | //new line doing the callback (if i want :)
|
|---|
| 310 | if((wantCallBack ||wantCallBack == undefined) && control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
|
|---|
| 311 | //to ensure retro-compatibility, wantCallBack must be considered as true by default
|
|---|
| 312 | // **** /MODIFICATION *****
|
|---|
| 313 |
|
|---|
| 314 | },// $.fn.rating.select
|
|---|
| 315 |
|
|---|
| 316 |
|
|---|
| 317 |
|
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 | readOnly: function(toggle, disable){ // make the control read-only (still submits value)
|
|---|
| 321 | var control = this.data('rating'); if(!control) return this;
|
|---|
| 322 | // setread-only status
|
|---|
| 323 | control.readOnly = toggle || toggle==undefined ? true : false;
|
|---|
| 324 | // enable/disable control value submission
|
|---|
| 325 | if(disable) $(control.inputs).attr("disabled", "disabled");
|
|---|
| 326 | else $(control.inputs).removeAttr("disabled");
|
|---|
| 327 | // Update rating control state
|
|---|
| 328 | this.data('rating', control);
|
|---|
| 329 | // Update display
|
|---|
| 330 | this.rating('draw');
|
|---|
| 331 | },// $.fn.rating.readOnly
|
|---|
| 332 |
|
|---|
| 333 | disable: function(){ // make read-only and never submit value
|
|---|
| 334 | this.rating('readOnly', true, true);
|
|---|
| 335 | },// $.fn.rating.disable
|
|---|
| 336 |
|
|---|
| 337 | enable: function(){ // make read/write and submit value
|
|---|
| 338 | this.rating('readOnly', false, false);
|
|---|
| 339 | }// $.fn.rating.select
|
|---|
| 340 |
|
|---|
| 341 | });
|
|---|
| 342 |
|
|---|
| 343 | /*--------------------------------------------------------*/
|
|---|
| 344 |
|
|---|
| 345 | /*
|
|---|
| 346 | ### Default Settings ###
|
|---|
| 347 | eg.: You can override default control like this:
|
|---|
| 348 | $.fn.rating.options.cancel = 'Clear';
|
|---|
| 349 | */
|
|---|
| 350 | $.fn.rating.options = { //$.extend($.fn.rating, { options: {
|
|---|
| 351 | cancel: 'Cancel Rating', // advisory title for the 'cancel' link
|
|---|
| 352 | cancelValue: '', // value to submit when user click the 'cancel' link
|
|---|
| 353 | split: 0, // split the star into how many parts?
|
|---|
| 354 |
|
|---|
| 355 | // Width of star image in case the plugin can't work it out. This can happen if
|
|---|
| 356 | // the jQuery.dimensions plugin is not available OR the image is hidden at installation
|
|---|
| 357 | starWidth: 16//,
|
|---|
| 358 |
|
|---|
| 359 | //NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
|
|---|
| 360 | //half: false, // just a shortcut to control.split = 2
|
|---|
| 361 | //required: false, // disables the 'cancel' button so user can only select one of the specified values
|
|---|
| 362 | //readOnly: false, // disable rating plugin interaction/ values cannot be changed
|
|---|
| 363 | //focus: function(){}, // executed when stars are focused
|
|---|
| 364 | //blur: function(){}, // executed when stars are focused
|
|---|
| 365 | //callback: function(){}, // executed when a star is clicked
|
|---|
| 366 | }; //} });
|
|---|
| 367 |
|
|---|
| 368 | /*--------------------------------------------------------*/
|
|---|
| 369 |
|
|---|
| 370 | /*
|
|---|
| 371 | ### Default implementation ###
|
|---|
| 372 | The plugin will attach itself to file inputs
|
|---|
| 373 | with the class 'multi' when the page loads
|
|---|
| 374 | */
|
|---|
| 375 | $(function(){
|
|---|
| 376 | $('input[type=radio].star').rating();
|
|---|
| 377 | });
|
|---|
| 378 |
|
|---|
| 379 |
|
|---|
| 380 |
|
|---|
| 381 | /*# AVOID COLLISIONS #*/
|
|---|
| 382 | })(jQuery);
|
|---|
| 383 | /*# AVOID COLLISIONS #*/
|
|---|