1;(function ( $, window, document, undefined ) { 2 3 // Create the defaults once 4 var pluginName = "ratingStar", 5 defaults = { 6 initialStar: 0, 7 selectedClass: 'is-selected', 8 hoverClass: 'is-hover', 9 afterClick: null 10 }; 11 12 // The actual plugin constructor 13 function Plugin( element, options ) { 14 this.$element = $(element); 15 16 this.options = $.extend( {}, defaults, options) ; 17 18 this._defaults = defaults; 19 this._name = pluginName; 20 21 this.init(); 22 } 23 24 Plugin.prototype = { 25 26 init: function() { 27 var self = this; 28 29 this.$starItems = this.$element.find('.c-rating-star__item'); 30 31 /* 1. Visualizing things on Hover - See next part for action on click */ 32 this.$starItems.on('mouseover', function(){ 33 self.onMouseOver(self, this); 34 }).on('mouseout', function(){ 35 self.onMouseOut(self, this); 36 }); 37 38 /* 2. Action to perform on click */ 39 this.$starItems.on('click', function(){ 40 self.onClick(self, this) 41 }); 42 }, 43 44 onClick: function(context, jqContext) { 45 var $this = $(jqContext); 46 var $stars = context.$starItems; 47 var onStar = parseInt($this.data('value'), 10); // The star currently selected 48 49 // remove all active star 50 $stars.removeClass('is-selected'); 51 52 for (i = 0; i < onStar; i++) { 53 $stars.eq(i).addClass('is-selected'); 54 } 55 56 var $selected = $this.parent().children('.is-selected').last(); 57 var ratingValue = parseInt($selected.data('value'), 10); 58 59 if (context.options.afterClick) { 60 context.options.afterClick(ratingValue, $selected); 61 } 62 }, 63 64 onMouseOver: function(context, jqContext) { 65 // The star currently mouse on 66 var currentStar = parseInt($(jqContext).data('value'), 10); 67 68 // all start item 69 var $stars = context.$starItems; 70 71 // Now highlight all the stars that's not after the current hovered star 72 for (i = 0; i <= currentStar; i++) { 73 if (i < currentStar) { 74 $stars.eq(i).addClass('is-hover'); 75 } else { 76 $stars.eq(i).removeClass('is-hover'); 77 } 78 } 79 80 console.log('mouse over on: ',jqContext); 81 console.log('current star: ', currentStar); 82 83 }, 84 85 onMouseOut: function (context, jqContext) { 86 for (i = 0; i <= context.$starItems.length; i++) { 87 context.$starItems.eq(i).removeClass('is-hover'); 88 } 89 } 90 }; 91 92 // A really lightweight plugin wrapper around the constructor, 93 // preventing against multiple instantiations 94 $.fn[pluginName] = function ( options ) { 95 return this.each(function () { 96 if (!$.data(this, "plugin_" + pluginName)) { 97 $.data(this, "plugin_" + pluginName, 98 new Plugin( this, options )); 99 } 100 }); 101 }; 102 103})( jQuery, window, document ); 104 105 106$(document).ready(function(){ 107 108$('form').on('submit', function (e) { 109 let rating = parseInt($('#rating').val(), 10); 110 let comment = $('#feedback-textarea').val().trim(); 111 let recaptchaResponse = grecaptcha.getResponse(); 112 113 let hasError = false; 114 115 // Reset errors 116 $('#rating-error').hide().text(''); 117 $('#comment-error').hide().text(''); 118 $('#g-recaptcha-error').remove(); // clear previous error 119 120 // Validate rating 121 if (isNaN(rating) || rating < 1 || rating > 5) { 122 $('#rating-error').text('Please select a valid rating between 1 and 5.').show(); 123 hasError = true; 124 } 125 126 // Validate comment 127 if (!comment) { 128 $('#comment-error').text('Please enter your feedback comment.').show(); 129 hasError = true; 130 } 131 132 // Validate reCAPTCHA 133 if (recaptchaResponse.length === 0) { 134 if ($('#g-recaptcha-error').length === 0) { 135 $('<div id="g-recaptcha-error" class="text-danger small mt-1">Please complete the reCAPTCHA.</div>') 136 .insertAfter('#g-recaptcha'); 137 } 138 hasError = true; 139 } 140 141 if (hasError) { 142 e.preventDefault(); // Stop form submission 143 } 144}); 145 146 147 $('#js-rating-star').ratingStar({ 148 afterClick: function (value, el) { 149 // Show message box (your existing behavior) 150 $('.c-box').fadeIn(200); 151 $('.c-box__body').html("<span>" + el.attr('title') + "</span>"); 152 153 // NEW: set rating value in hidden/visible input 154 $('#rating').val(value); 155 } 156 }); 157 158});
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.