PluginProbe
MyBookTable Bookstore by Stormhill Media / trunk
MyBookTable Bookstore by Stormhill Media vtrunk
3.6.5 trunk
mybooktable / js / lib / jquery.rating.js

jquery.rating.js in MyBookTable Bookstore by Stormhill Media trunk, at js/lib/jquery.rating.js

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