1/** 2* jQuery Bar Rating Plugin v1.1.4 3* 4* http://github.com/antennaio/jquery-bar-rating 5* 6* Copyright (c) 2012-2015 Kazik Pietruszewski 7* 8* Dual licensed under the MIT and GPL licenses: 9* http://www.opensource.org/licenses/mit-license.php 10* http://www.gnu.org/licenses/gpl.html 11*/ 12(function (factory) { 13 if (typeof define === 'function' && define.amd) { 14 // AMD 15 define(['jquery'], factory); 16 } else if (typeof module === 'object' && module.exports) { 17 // Node/CommonJS 18 module.exports = factory(require('jquery')); 19 } else { 20 // browser globals 21 factory(jQuery); 22 } 23} (function ($) { 24 25 var BarRating = (function () { 26 27 function BarRating() { 28 var self = this; 29 30 // wrap element in a wrapper div 31 var wrapElement = function () { 32 var classes = [self.options.wrapperClass]; 33 34 if (self.options.theme !== '') { 35 classes.push('br-theme-' + self.options.theme); 36 } 37 38 self.$elem.wrap($('<div>', { 39 'class': classes.join(' ') 40 })); 41 }; 42 43 // unwrap element 44 var unwrapElement = function () { 45 self.$elem.unwrap(); 46 }; 47 48 // return initial option 49 var findInitialOption = function () { 50 var option; 51 52 if (self.options.initialRating) { 53 option = $('option[value="' + self.options.initialRating + '"]', self.$elem); 54 } else { 55 option = $('option:selected', self.$elem); 56 } 57 58 return option; 59 }; 60 61 // get data 62 var getData = function (key) { 63 var data = self.$elem.data('barrating'); 64 65 if (typeof key !== 'undefined') { 66 return data[key]; 67 } 68 69 return data; 70 }; 71 72 // set data 73 var setData = function (key, value) { 74 if (value !== null && typeof value === 'object') { 75 self.$elem.data('barrating', value); 76 } else { 77 self.$elem.data('barrating')[key] = value; 78 } 79 }; 80 81 // save data on element 82 var saveDataOnElement = function () { 83 var $opt = findInitialOption(); 84 85 setData(null, { 86 userOptions: self.options, 87 88 // initial rating based on the OPTION value 89 ratingValue: $opt.val(), 90 ratingText: ($opt.data('html')) ? $opt.data('html') : $opt.text(), 91 92 // rating will be restored by calling clear method 93 originalRatingValue: $opt.val(), 94 originalRatingText: ($opt.data('html')) ? $opt.data('html') : $opt.text(), 95 96 // read-only state 97 readOnly: self.options.readonly, 98 99 // first OPTION empty - allow deselecting of ratings 100 deselectable: (!self.$elem.find('option:first').val()) ? true : false 101 }); 102 }; 103 104 // remove data on element 105 var removeDataOnElement = function () { 106 self.$elem.removeData('barrating'); 107 }; 108 109 // return current rating text 110 var ratingText = function () { 111 return getData('ratingText'); 112 }; 113 114 // return current rating value 115 var ratingValue = function () { 116 return getData('ratingValue'); 117 }; 118 119 // build widget and return jQuery element 120 var buildWidget = function () { 121 var $w = $('<div>', { 'class': 'br-widget' }); 122 123 // create A elements that will replace OPTIONs 124 self.$elem.find('option').each(function () { 125 var val, text, html, $a; 126 127 val = $(this).val(); 128 129 // create ratings - but only if val is defined 130 if (val) { 131 text = $(this).text(); 132 html = $(this).data('html'); 133 if (html) { text = html; } 134 135 $a = $('<a>', { 136 'href': '#', 137 'data-rating-value': val, 138 'data-rating-text': text, 139 'html': (self.options.showValues) ? text : '' 140 }); 141 142 $w.append($a); 143 } 144 145 }); 146 147 // append .br-current-rating div to the widget 148 if (self.options.showSelectedRating) { 149 $w.append($('<div>', { 'text': '', 'class': 'br-current-rating' })); 150 } 151 152 // additional classes for the widget 153 if (self.options.reverse) { 154 $w.addClass('br-reverse'); 155 } 156 157 if (self.options.readonly) { 158 $w.addClass('br-readonly'); 159 } 160 161 return $w; 162 }; 163 164 // return a jQuery function name depending on the 'reverse' setting 165 var nextAllorPreviousAll = function () { 166 if (getData('userOptions').reverse) { 167 return 'nextAll'; 168 } else { 169 return 'prevAll'; 170 } 171 }; 172 173 // set the value of the select field 174 var setSelectFieldValue = function (value) { 175 // change selected OPTION in the select field (hidden) 176 self.$elem.find('option[value="' + value + '"]').prop('selected', true); 177 self.$elem.change(); 178 }; 179 180 // display the currently selected rating 181 var showSelectedRating = function (text) { 182 // text undefined? 183 text = text ? text : ratingText(); 184 185 // update .br-current-rating div 186 if (self.options.showSelectedRating) { 187 self.$elem.parent().find('.br-current-rating').text(text); 188 } 189 }; 190 191 // apply style by setting classes on elements 192 var applyStyle = function () { 193 // remove classes 194 self.$widget.find('a').removeClass('br-selected br-current'); 195 196 // add classes 197 self.$widget.find('a[data-rating-value="' + ratingValue() + '"]') 198 .addClass('br-selected br-current')[nextAllorPreviousAll()]() 199 .addClass('br-selected'); 200 }; 201 202 // check if the element is deselectable? 203 var isDeselectable = function ($element) { 204 return ($element.hasClass('br-current') && getData('deselectable'));
vendor: 9,918 bytes, lines 205-488
205 }; 206 207 // handle click events 208 var attachClickHandler = function ($elements) { 209 $elements.on('click.barrating', function (event) { 210 var $a = $(this), 211 options = getData('userOptions'), 212 value, 213 text; 214 215 event.preventDefault(); 216 217 $elements.removeClass('br-active br-selected'); 218 $a.addClass('br-selected')[nextAllorPreviousAll()]() 219 .addClass('br-selected'); 220 221 value = $a.attr('data-rating-value'); 222 text = $a.attr('data-rating-text'); 223 224 // is current and deselectable? 225 if (isDeselectable($a)) { 226 $a.removeClass('br-selected br-current')[nextAllorPreviousAll()]() 227 .removeClass('br-selected br-current'); 228 value = ''; text = ''; 229 } else { 230 $elements.removeClass('br-current'); 231 $a.addClass('br-current'); 232 } 233 234 // remember selected rating 235 setData('ratingValue', value); 236 setData('ratingText', text); 237 238 setSelectFieldValue(value); 239 showSelectedRating(text); 240 241 // onSelect callback 242 options.onSelect.call( 243 self, 244 ratingValue(), 245 ratingText(), 246 event 247 ); 248 249 return false; 250 }); 251 }; 252 253 // handle mouseenter events 254 var attachMouseEnterHandler = function ($elements) { 255 $elements.on('mouseenter.barrating focus.barrating', function () { 256 var $a = $(this); 257 258 $elements.removeClass('br-active br-selected'); 259 $a.addClass('br-active')[nextAllorPreviousAll()]() 260 .addClass('br-active'); 261 262 showSelectedRating($a.attr('data-rating-text')); 263 }); 264 }; 265 266 // handle mouseleave events 267 var attachMouseLeaveHandler = function ($elements) { 268 self.$widget.on('mouseleave.barrating blur.barrating', function () { 269 $elements.removeClass('br-active'); 270 showSelectedRating(); 271 applyStyle(); 272 }); 273 }; 274 275 // somewhat primitive way to remove 300ms click delay on touch devices 276 // for a more advanced solution consider setting `fastClicks` option to false 277 // and using a library such as fastclick (https://github.com/ftlabs/fastclick) 278 var fastClicks = function ($elements) { 279 $elements.on('touchstart.barrating', function (event) { 280 event.preventDefault(); 281 event.stopPropagation(); 282 283 $(this).click(); 284 }); 285 }; 286 287 // disable clicks 288 var disableClicks = function ($elements) { 289 $elements.on('click.barrating', function (event) { 290 event.preventDefault(); 291 }); 292 }; 293 294 var attachHandlers = function ($elements) { 295 // attach click event handler 296 attachClickHandler($elements); 297 298 if (self.options.hoverState) { 299 // attach mouseenter event handler 300 attachMouseEnterHandler($elements); 301 302 // attach mouseleave event handler 303 attachMouseLeaveHandler($elements); 304 } 305 }; 306 307 var detachHandlers = function ($elements) { 308 // remove event handlers in the ".barrating" namespace 309 $elements.off('.barrating'); 310 }; 311 312 var setupHandlers = function (readonly) { 313 $elements = self.$widget.find('a'); 314 315 if (fastClicks) { 316 fastClicks($elements); 317 } 318 319 if (readonly) { 320 detachHandlers($elements); 321 disableClicks($elements); 322 } else { 323 attachHandlers($elements); 324 } 325 }; 326 327 this.show = function () { 328 // run only once 329 if (getData()) return; 330 331 // wrap element 332 wrapElement(); 333 334 // save data 335 saveDataOnElement(); 336 337 // build & append widget to the DOM 338 self.$widget = buildWidget(); 339 self.$widget.insertAfter(self.$elem); 340 341 applyStyle(); 342 343 showSelectedRating(); 344 345 setupHandlers(self.options.readonly); 346 347 // hide the select field 348 self.$elem.hide(); 349 }; 350 351 this.readonly = function (state) { 352 if (typeof state !== 'boolean' || getData('readOnly') == state) return; 353 354 setupHandlers(state); 355 setData('readOnly', state); 356 self.$widget.toggleClass('br-readonly'); 357 }; 358 359 this.set = function (value) { 360 var options = getData('userOptions'); 361 362 if (!self.$elem.find('option[value="' + value + '"]').val()) return; 363 364 // set data 365 setData('ratingValue', value); 366 setData('ratingText', self.$elem.find('option[value="' + value + '"]').text()); 367 368 setSelectFieldValue(ratingValue()); 369 showSelectedRating(ratingText()); 370 371 applyStyle(); 372 373 // onSelect callback 374 if (!options.silent) { 375 options.onSelect.call( 376 this, 377 ratingValue(), 378 ratingText() 379 ); 380 } 381 }; 382 383 this.clear = function () { 384 var options = getData('userOptions'); 385 386 // restore original data 387 setData('ratingValue', getData('originalRatingValue')); 388 setData('ratingText', getData('originalRatingText')); 389 390 setSelectFieldValue(ratingValue()); 391 showSelectedRating(ratingText()); 392 393 applyStyle(); 394 395 // onClear callback 396 options.onClear.call( 397 this, 398 ratingValue(), 399 ratingText() 400 ); 401 }; 402 403 this.destroy = function () { 404 var value = ratingValue(); 405 var text = ratingText(); 406 var options = getData('userOptions'); 407 408 // detach handlers 409 detachHandlers(self.$widget.find('a')); 410 411 // remove widget 412 self.$widget.remove(); 413 414 // remove data 415 removeDataOnElement(); 416 417 // unwrap the element 418 unwrapElement(); 419 420 // show the element 421 self.$elem.show(); 422 423 // onDestroy callback 424 options.onDestroy.call( 425 this, 426 value, 427 text 428 ); 429 }; 430 } 431 432 BarRating.prototype.init = function (options, elem) { 433 this.$elem = $(elem); 434 this.options = $.extend({}, $.fn.barrating.defaults, options); 435 436 return this.options; 437 }; 438 439 return BarRating; 440 })(); 441 442 $.fn.barrating = function (method, options) { 443 return this.each(function () { 444 var plugin = new BarRating(); 445 446 // plugin works with select fields 447 if (!$(this).is('select')) { 448 $.error('Sorry, this plugin only works with select fields.'); 449 } 450 451 // method supplied 452 if (plugin.hasOwnProperty(method)) { 453 plugin.init(options, this); 454 if (method === 'show') { 455 return plugin.show(options); 456 } else { 457 // plugin exists? 458 if (plugin.$elem.data('barrating')) { 459 plugin.$widget = $(this).next('.br-widget'); 460 return plugin[method](options); 461 } 462 } 463 464 // no method supplied or only options supplied 465 } else if (typeof method === 'object' || !method) { 466 options = method; 467 plugin.init(options, this); 468 return plugin.show(); 469 470 } else { 471 $.error('Method ' + method + ' does not exist on jQuery.barrating'); 472 } 473 }); 474 }; 475 476 $.fn.barrating.defaults = { 477 theme: '', 478 initialRating: null, // initial rating 479 showValues: false, // display rating values on the bars? 480 showSelectedRating: true, // append a div with a rating to the widget? 481 reverse: false, // reverse the rating? 482 readonly: false, // make the rating ready-only? 483 fastClicks: true, // remove 300ms click delay on touch devices? 484 hoverState: true, // change state on hover? 485 silent: false, // supress callbacks when controlling ratings programatically 486 wrapperClass: 'br-wrapper', // class applied to wrapper div 487 onSelect: function (value, text, event) { 488 }
488, // callback fired when a rating is selected 489 onClear: function (value, text) { 490 }, // callback fired when a rating is cleared 491 onDestroy: function (value, text) { 492 } // callback fired when a widget is destroyed 493 }; 494 495 $.fn.barrating.BarRating = BarRating; 496 497}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.