[2] | 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 #*/
|
---|