1"use strict"; 2jQuery(document).ready(function ($) { 3 //Added active class in the eventin menu in dokan leftmenu 4 const _pathname = window.location.pathname.toString(); 5 const create_event = "/eventin/create_event/"; 6 const vendor_event = "/eventin/vendor_event/"; 7 if (_pathname.includes(create_event) || _pathname.includes(vendor_event)) { 8 $(".dokan-dashboard-menu").find("li.eventin").addClass("active"); 9 } 10 11 /*================================ 12 speaker slider 13 ===================================*/ 14 var $scope = $(".speaker_shortcode_slider"); 15 if ($scope.length > 0) { 16 $($scope).each(function () { 17 var $this = $(this); 18 speaker_sliders_pro($, $this); 19 }); 20 } 21 22 /*================================ 23 speaker slider 24 ===================================*/ 25 var $scope = $(".event-slider-shortcode"); 26 event_sliders_pro($, $scope); 27 28 /*================================ 29 Event accordion 30 ===================================*/ 31 32 $(".etn-content-item > .etn-accordion-heading").on("click", function (e) { 33 e.preventDefault(); 34 if ($(this).hasClass("active")) { 35 $(this).removeClass("active"); 36 $(this).siblings(".etn-acccordion-contents").slideUp(200); 37 $(".etn-content-item > .etn-accordion-heading i") 38 .removeClass("etn-minus") 39 .addClass("etn-plus"); 40 } else { 41 $(".etn-content-item > .etn-accordion-heading i") 42 .removeClass("etn-minus") 43 .addClass("etn-plus"); 44 $(this).find("i").removeClass("etn-plus").addClass("etn-minus"); 45 $(".etn-content-item > .etn-accordion-heading").removeClass("active"); 46 $(this).addClass("active"); 47 $(".etn-acccordion-contents").slideUp(200); 48 $(this).siblings(".etn-acccordion-contents").slideDown(200); 49 } 50 }); 51 52 /*================================ 53 // countdown 54 ===================================*/ 55 const main_block = $(".etn_count_down_block"); 56 if (main_block.length) { 57 count_down($, main_block); 58 } 59 60 /*================================ 61 // Advanced search toggle 62 ===================================*/ 63 if ($(".etn-filter-icon").length > 0) { 64 $(".etn-filter-icon").on("click", function () { 65 $(this).parents().find(".etn_event_inline_form_bottom").slideToggle(); 66 }); 67 } 68 69 /*================================ 70 // Certificate generate 71 ===================================*/ 72 const certificateButton = $(".etn-certificate-download"); 73 certificateButton.on("click", function (e) { 74 e.preventDefault(); 75 etnCreateCertificate(certificateButton); 76 }); 77 78 /*==================================================== 79 * // Event bulk attendee field value update script 80 * ====================================================*/ 81 $("#etn_bulk_attendee").on("change", function () { 82 const totalVariations = $(".etn-ticket-single-variation-details").length; 83 const submitButton = $(".attendee_submit"); 84 const isChecked = $(this).is(":checked"); 85 const checkbox = $(this); 86 checkbox.prop("checked", isChecked); 87 88 for ( 89 let variationIndex = 0; 90 variationIndex < totalVariations; 91 variationIndex++ 92 ) { 93 const totalTicketQuantity = checkbox.data(`total_ticket_quantity`); 94 95 for ( 96 let quantityIndex = 0; 97 quantityIndex < totalTicketQuantity; 98 quantityIndex++ 99 ) { 100 const element = quantityIndex + 1; 101 const nameElement = $( 102 `#ticket_${variationIndex}_attendee_name_${element}` 103 ); 104 const emailElement = $( 105 `#ticket_${variationIndex}_attendee_email_${element}` 106 ); 107 const phoneElement = $( 108 `#ticket_${variationIndex}_attendee_phone_${element}` 109 ); 110 const fields = [nameElement, emailElement, phoneElement]; 111 112 fields.forEach((field) => { 113 if (isChecked) { 114 field.removeClass("attendee_error"); 115 const fieldType = field.attr("type"); 116 if (fieldType === "email") { 117 emailElement.val(`attendee${element}@test.com`); 118 } else if (fieldType === "tel") { 119 field.val(`0123456789${element}`); 120 } else { 121 field.val(`Attendee ${element}`); 122 } 123 } else { 124 field.val("").addClass("attendee_error"); 125 } 126 }); 127 } 128 } 129 submitButton 130 .prop("disabled", !isChecked) 131 .toggleClass("attendee_submit_disable", !isChecked); 132 }); 133}); 134 135// etnCreateCertificate.js 136async function generateCertificateImage(element) { 137 // Wait for all images to load first 138 await Promise.all( 139 Array.from(element.querySelectorAll("img")).map((img) => { 140 if (img.complete) return Promise.resolve(); 141 return new Promise((resolve) => { 142 img.onload = resolve; 143 img.onerror = resolve; 144 }); 145 }) 146 ); 147 148 // Use html2canvas with proper config 149 const canvas = await window.html2canvas(element, { 150 useCORS: true, // Handle cross-origin images 151 allowTaint: true, // Allow loading cross-origin images 152 scrollX: 0, // Ensure proper positioning 153 scrollY: 0, 154 scale: 1.5, // Higher quality 155 logging: true, // Help debug issues 156 width: element.offsetWidth, 157 height: element.offsetHeight, 158 backgroundColor: null, // Preserve the element's own background (e.g. Elementor styles) 159 onclone: function(clonedDoc, clonedEl) { 160 // Inherit background from parent elements (e.g. Elementor section gradient) 161 // html2canvas only captures the target element's styles, so backgrounds 162 // applied to parent containers (like Elementor sections) would be lost. 163 var parent = element.parentElement; 164 while (parent && parent !== document.body) { 165 var parentStyle = window.getComputedStyle(parent); 166 var parentBgImage = parentStyle.backgroundImage; 167 var parentBgColor = parentStyle.backgroundColor; 168 var hasBgImage = parentBgImage && parentBgImage !== 'none'; 169 var hasBgColor = parentBgColor && 170 parentBgColor !== 'rgba(0, 0, 0, 0)' && 171 parentBgColor !== 'transparent'; 172 173 if (hasBgImage || hasBgColor) { 174 var elStyle = window.getComputedStyle(element); 175 var elBgImage = elStyle.backgroundImage; 176 177 if (hasBgImage) { 178 if (elBgImage && elBgImage !== 'none') { 179 // Layer element's background on top of parent's background 180 clonedEl.style.backgroundImage = elBgImage + ', ' + parentBgImage; 181 clonedEl.style.backgroundPosition = elStyle.backgroundPosition + ', center'; 182 clonedEl.style.backgroundSize = elStyle.backgroundSize + ', cover'; 183 } else { 184 clonedEl.style.backgroundImage = parentBgImage; 185 } 186 } 187 188 if (hasBgColor) { 189 clonedEl.style.backgroundColor = parentBgColor; 190 } 191 192 break; 193 } 194 parent = parent.parentElement; 195 } 196 } 197 }); 198 199 return canvas.toDataURL("image/png"); 200} 201 202async function etnCreateCertificate(downloadButton) { 203 'use strict'; 204 205 const jsPDF = window.jspdf.jsPDF; 206 207 if(downloadButton) downloadButton.addClass("loading"); 208 209 // Try both new and legacy selectors 210 const element = 211 document.querySelector(".etn-downloadable-container") || document.querySelector(".eventin-container-block") || 212 document.querySelector(".etn-pdf-content"); 213 if (!element) { 214 throw new Error("Certificate container not found"); 215 } 216 217 // Wait for all images to load 218 await Promise.all( 219 Array.from(element.querySelectorAll('img')).map((img) => { 220 if (img.complete) return Promise.resolve(); 221 return new Promise((resolve) => { 222 img.onload = resolve; 223 img.onerror = resolve; 224 }); 225 }) 226 ); 227 228 try { 229 230 // Get dimensions from element 231 const computedStyle = window.getComputedStyle(element); 232 const elementWidth = element.offsetWidth || parseFloat(computedStyle.width); 233 const elementHeight = 234 element.offsetHeight || parseFloat(computedStyle.height); 235 236 const dataUrl = await generateCertificateImage(element); 237 const img = new Image(); 238 239 return new Promise((resolve) => { 240 img.onload = () => { 241 242 const orientation = elementWidth > elementHeight ? "l" : "p"; 243 244 const doc = new jsPDF({ 245 orientation, 246 unit: "px", 247 format: "a4", 248 }); 249 250 const pageWidth = doc.internal.pageSize.getWidth(); 251 const pageHeight = doc.internal.pageSize.getHeight(); 252 253 const scale = Math.min( 254 (pageWidth - 20) / elementWidth, 255 (pageHeight - 20) / elementHeight 256 ); 257 258 const width = elementWidth * scale; 259 const height = elementHeight * scale; 260 261 const x = (pageWidth - width) / 2; 262 const y = (pageHeight - height) / 2; 263 264 doc.addImage(img, "PNG", x, y, width, height,undefined, "FAST"); 265 const filename = `document-${new Date().toISOString().slice(0, 10)}.pdf`; 266 doc.save(filename); 267 downloadButton.removeClass("loading"); 268 }; 269 270 img.onerror = (error) => { 271 console.error("Certificate image generation failed:", error); 272 downloadButton.removeClass("loading"); 273 resolve(false); 274 }; 275 276 img.src = dataUrl; 277 }); 278 } catch (error) { 279 console.error("Certificate generation failed:", error); 280 downloadButton.removeClass("loading"); 281 } 282} 283 284// Event Countdown Function 285 286function count_down($, $scope) { 287 const countdownContainer = $scope.find(".etn-event-countdown-wrap"); 288 if (countdownContainer.length) { 289 $scope.find(".etn-countdown-parent").countdown({ 290 date: countdownContainer.data("start-date"), 291 day: countdownContainer.data("date-texts").day, 292 days: countdownContainer.data("date-texts").days, 293 hour: countdownContainer.data("date-texts").hr, 294 hours: countdownContainer.data("date-texts").hrs, 295 minute: countdownContainer.data("date-texts").min,
296 minutes: countdownContainer.data("date-texts").mins, 297 second: countdownContainer.data("date-texts").sec, 298 seconds: countdownContainer.data("date-texts").secs, 299 hideOnComplete: true, 300 offset: countdownContainer.data("date-texts").offset, 301 }); 302 } 303} 304 305// print order details 306function etn_pro_pirnt_content_area(divContents) { 307 "use strict"; 308 var mywindow = window.open("", "PRINT", "height=400,width=800"); 309 mywindow.document.write( 310 '<style type="text/css">' + 311 ".woocommerce-column--1, .woocommerce-column--2{display:inline-block; float: none; width: 300px; vertical-align: top;} .woocommerce-table tr th{text-align:left; width: 300px; }" + 312 "</style>" 313 ); 314 315 var contentToPrint = 316 document.getElementsByClassName(divContents)[0].innerHTML; 317 contentToPrint = contentToPrint.split('<div class="extra-buttons">')[0]; 318 mywindow.document.write("</head><body >"); 319 mywindow.document.write(contentToPrint); 320 mywindow.document.write("</body></html>"); 321 mywindow.document.close(); // necessary for IE >= 10 322 mywindow.focus(); // necessary for IE >= 10*/ 323 mywindow.print(); 324 return true; 325} 326 327//download pdf 328function etn_pro_download_pdf() { 329 var contentToPrint = 330 document.getElementsByClassName("woocommerce-order")[0].innerHTML; 331 var source = contentToPrint.split('<div class="extra-buttons">')[0]; 332 var filename = "invoice"; 333 jQuery(".woocommerce-order").html(source); 334 var divToPrint = jQuery(".woocommerce-order")[0]; 335 336 // create custom canvas for a better resolution 337 var w = 1000; 338 var h = 1000; 339 var canvas = document.createElement("canvas"); 340 canvas.width = w * 5; 341 canvas.height = h * 5; 342 canvas.style.width = w + "px"; 343 canvas.style.height = h + "px"; 344 var context = canvas.getContext("2d"); 345 context.scale(5, 5); 346 347 html2canvas(divToPrint, { 348 scale: 4, 349 dpi: 288, 350 onrendered: function (canvas) { 351 var data = canvas.toDataURL("image/png", 1); 352 var docDefinition = { 353 content: [ 354 { 355 image: data, 356 width: 500, 357 }, 358 ], 359 }; 360 pdfMake.createPdf(docDefinition).download(filename + ".pdf"); 361 }, 362 }); 363 window.setTimeout(function () { 364 location.reload(); 365 }, 500); 366} 367 368function getSwiperOption({ count, space, autoplays }) { 369 return { 370 slidesPerView: count, 371 spaceBetween: space, 372 navigation: { 373 nextEl: ".swiper-button-next", 374 prevEl: ".swiper-button-prev", 375 }, 376 pagination: { 377 el: ".swiper-pagination", 378 clickable: true, 379 }, 380 autoplay: autoplays, 381 382 paginationClickable: true, 383 breakpoints: { 384 320: { 385 slidesPerView: 1, 386 }, 387 600: { 388 slidesPerView: 2, 389 }, 390 1024: { 391 slidesPerView: count, 392 }, 393 }, 394 }; 395} 396 397// speaker sliders pro 398function speaker_sliders_pro($, $scope) { 399 var $container = $scope.find(".etn-speaker-slider"); 400 var count = $container.data("count"); 401 var space = $container.data("space"); 402 var autoplay = $container.data("autoplay"); 403 var autoplays = autoplay == "yes" ? true : false; 404 405 if ($container.length > 0) { 406 $($container).each(function (index, element) { 407 var mySwiper = new Swiper( 408 element, 409 getSwiperOption({ count, space: 20, autoplays }) 410 ); 411 }); 412 } 413} 414 415// Event sliders pro 416function event_sliders_pro($, $scope) { 417 var $container = $scope.find(".etn-event-slider"); 418 var count = $container.data("count"); 419 var autoplay = $container.data("autoplay"); 420 var autoplays = autoplay == "yes" ? true : false; 421 if ($container.length > 0) { 422 $($container).each(function (index, element) { 423 var mySwiper = new Swiper( 424 element, 425 getSwiperOption({ count, space: 20, autoplays }) 426 ); 427 }); 428 } 429}
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.