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