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 #*/
|
---|