app/site-content/js/jquery.rating.js
changeset 28 be65e84e7d03
equal deleted inserted replaced
27:37612f295cd4 28:be65e84e7d03
       
     1 /*
       
     2  ### jQuery Star Rating Plugin v3.12 - 2009-04-16 ###
       
     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 		select: function(value){ // select a value
       
   259 			var control = this.data('rating'); if(!control) return this;
       
   260 			// do not execute when control is in read-only mode
       
   261 			if(control.readOnly) return;
       
   262 			// clear selection
       
   263 			control.current = null;
       
   264 			// programmatically (based on user input)
       
   265 			if(typeof value!='undefined'){
       
   266 			 // select by index (0 based)
       
   267 				if(typeof value=='number')
       
   268  			 return $(control.stars[value]).rating('select');
       
   269 				// select by literal value (must be passed as a string
       
   270 				if(typeof value=='string')
       
   271 					//return 
       
   272 					$.each(control.stars, function(){
       
   273 						if($(this).data('rating.input').val()==value) $(this).rating('select');
       
   274 					});
       
   275 			}
       
   276 			else
       
   277 				control.current = this[0].tagName=='INPUT' ? 
       
   278 				 this.data('rating.star') : 
       
   279 					(this.is('.rater-'+ control.serial) ? this : null);
       
   280 			
       
   281 			// Update rating control state
       
   282 			this.data('rating', control);
       
   283 			// Update display
       
   284 			this.rating('draw');
       
   285 			// find data for event
       
   286 			var input = $( control.current ? control.current.data('rating.input') : null );
       
   287 			// click callback, as requested here: http://plugins.jquery.com/node/1655
       
   288 			if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
       
   289 		},// $.fn.rating.select
       
   290 		
       
   291 		readOnly: function(toggle, disable){ // make the control read-only (still submits value)
       
   292 			var control = this.data('rating'); if(!control) return this;
       
   293 			// setread-only status
       
   294 			control.readOnly = toggle || toggle==undefined ? true : false;
       
   295 			// enable/disable control value submission
       
   296 			if(disable) $(control.inputs).attr("disabled", "disabled");
       
   297 			else     			$(control.inputs).removeAttr("disabled");
       
   298 			// Update rating control state
       
   299 			this.data('rating', control);
       
   300 			// Update display
       
   301 			this.rating('draw');
       
   302 		},// $.fn.rating.readOnly
       
   303 		
       
   304 		disable: function(){ // make read-only and never submit value
       
   305 			this.rating('readOnly', true, true);
       
   306 		},// $.fn.rating.disable
       
   307 		
       
   308 		enable: function(){ // make read/write and submit value
       
   309 			this.rating('readOnly', false, false);
       
   310 		}// $.fn.rating.select
       
   311 		
       
   312  });
       
   313 	
       
   314 	/*--------------------------------------------------------*/
       
   315 	
       
   316 	/*
       
   317 		### Default Settings ###
       
   318 		eg.: You can override default control like this:
       
   319 		$.fn.rating.options.cancel = 'Clear';
       
   320 	*/
       
   321 	$.fn.rating.options = { //$.extend($.fn.rating, { options: {
       
   322 			cancel: 'Cancel Rating',   // advisory title for the 'cancel' link
       
   323 			cancelValue: '',           // value to submit when user click the 'cancel' link
       
   324 			split: 0,                  // split the star into how many parts?
       
   325 			
       
   326 			// Width of star image in case the plugin can't work it out. This can happen if
       
   327 			// the jQuery.dimensions plugin is not available OR the image is hidden at installation
       
   328 			starWidth: 16//,
       
   329 			
       
   330 			//NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
       
   331 			//half:     false,         // just a shortcut to control.split = 2
       
   332 			//required: false,         // disables the 'cancel' button so user can only select one of the specified values
       
   333 			//readOnly: false,         // disable rating plugin interaction/ values cannot be changed
       
   334 			//focus:    function(){},  // executed when stars are focused
       
   335 			//blur:     function(){},  // executed when stars are focused
       
   336 			//callback: function(){},  // executed when a star is clicked
       
   337  }; //} });
       
   338 	
       
   339 	/*--------------------------------------------------------*/
       
   340 	
       
   341 	/*
       
   342 		### Default implementation ###
       
   343 		The plugin will attach itself to file inputs
       
   344 		with the class 'multi' when the page loads
       
   345 	*/
       
   346 	$(function(){
       
   347 	 $('input[type=radio].star').rating();
       
   348 	});
       
   349 	
       
   350 	
       
   351 	
       
   352 /*# AVOID COLLISIONS #*/
       
   353 })(jQuery);
       
   354 /*# AVOID COLLISIONS #*/