1/* 2 * Custom code goes here. 3 * A template should always ship with an empty custom.js 4 */ 5 6// notificación -> función addNotification do módulo mailalerts 7function addNotification() { 8 var ids = $("div.js-mailalert input[type=hidden]"); 9 10 $.ajax({ 11 type: "POST", 12 url: $("div.js-mailalert").data("url"), 13 data: 14 "id_product=" + 15 ids[0].value + 16 "&id_product_attribute=" + 17 ids[1].value + 18 "&customer_email=" + 19 $("div.js-mailalert input[type=email]").val(), 20 success: function (resp) { 21 resp = JSON.parse(resp); 22 23 $("div.js-mailalert span.js-mailalert-response") 24 .html(resp.message) 25 .show(); 26 if (!resp.error) { 27 $("div.js-mailalert a").hide(); 28 $("div.js-mailalert input[type=email]").hide(); 29 } 30 }, 31 }); 32 return false; 33} 34 35$(function () { 36 // span data location 37 $("span[data-loc]").click(function () { 38 var dataLoc = $(this).attr("data-loc"); 39 var dataLoc = atob(dataLoc); 40 window.location = dataLoc; 41 }); 42 43 // notificacións 44 let $body = $("body"); 45 let $productDiv = $("#product"); 46 47 $body.on("click", ".js-availabilitynotification", function (event) { 48 let elm = $(event.target).closest(".js-product-miniature"); 49 prestashop.emit("clickAvailabilityNotification", { 50 miniature: elm, 51 dataset: elm.data(), 52 }); 53 event.preventDefault(); 54 }); 55 56 prestashop.on("clickAvailabilityNotification", function (elm) { 57 let data = { 58 action: "availabilitynotification", 59 id_product: elm.dataset.idProduct, 60 id_product_attribute: elm.dataset.idProductAttribute, 61 }; 62 63 let prevProductMinature = elm.miniature 64 .parent() 65 .prev() 66 .children(".js-product-miniature") 67 .first(); 68 let nextProductMinature = elm.miniature 69 .parent() 70 .next() 71 .children(".js-product-miniature") 72 .first(); 73 74 $.post(prestashop.urls.pages.product, data, null, "json") 75 .then(function (resp) { 76 let $notificationModal = $(".modal.availabilitynotification").first(); 77 if ($notificationModal.length) { 78 showAvailabilityNotificationModal( 79 $body, 80 resp, 81 prevProductMinature, 82 nextProductMinature, 83 $notificationModal, 84 ); 85 } else { 86 showAvailabilityNotificationModal( 87 $body, 88 resp, 89 prevProductMinature, 90 nextProductMinature, 91 false, 92 ); 93 } 94 }) 95 .fail((resp) => { 96 prestashop.emit("handleError", { 97 eventType: "clickAvailabilityNotification", 98 resp: resp, 99 }); 100 }); 101 }); 102 103 var showAvailabilityNotificationModal = ( 104 $body, 105 resp, 106 prevProductMinature, 107 nextProductMinature, 108 $oldModal, 109 ) => { 110 var availabilityNotificationAfterShown = (productModal) => { 111 $productCover = productModal.find("#product-images-large"); 112 113 new Swiper($productCover[0], { 114 loop: false, 115 effect: "fade", 116 preloadImages: false, 117 lazy: { 118 loadPrevNext: true, 119 }, 120 navigation: { 121 nextEl: ".swiper-button-next", 122 prevEl: ".swiper-button-prev", 123 }, 124 }); 125 126 if (iqitTheme.pp_zoom == "inner") { 127 let $easyzoom = productModal.find(".easyzoom-product").easyZoom(); 128 } else { 129 productModal.find(".js-easyzoom-trigger").on("click", (event) => { 130 event.preventDefault(); 131 }); 132 } 133 134 $(".modal-backdrop.show").first().addClass("backdrop-second"); 135 136 prestashop.emit("availabilityNotificationShown", { 137 modal: productModal, 138 }); 139 }; 140 141 if (!$oldModal) { 142 $body.append(resp.availabilitynotification_html); 143 } else { 144 $oldModal 145 .find("#availabilitynotification-modal-product-content") 146 .replaceWith( 147 $(resp.availabilitynotification_html).find( 148 "#availabilitynotification-modal-product-content", 149 ), 150 ); 151 } 152 153 let productModal = $(`#availabilitynotification-modal`); 154 let $prevAvailabilityNotificationBtn = $( 155 "#js-availabilitynotification-prev-btn", 156 ); 157 let $nextAvailabilityNotificationBtn = $( 158 "#js-availabilitynotification-next-btn", 159 ); 160 161 if (!prevProductMinature.length) { 162 $prevAvailabilityNotificationBtn.hide(); 163 } 164 if (!nextProductMinature.length) { 165 $nextAvailabilityNotificationBtn.hide(); 166 } 167 168 $prevAvailabilityNotificationBtn.on("click", function (event) { 169 let elm = prevProductMinature; 170 prestashop.emit("clickAvailabilityNotification", { 171 miniature: elm, 172 dataset: elm.data(), 173 }); 174 event.preventDefault(); 175 }); 176 177 $nextAvailabilityNotificationBtn.on("click", function (event) { 178 let elm = nextProductMinature; 179 prestashop.emit("clickAvailabilityNotification", { 180 miniature: elm, 181 dataset: elm.data(), 182 }); 183 event.preventDefault(); 184 }); 185 186 if (!$oldModal) { 187 productModal.modal("show"); 188 productModal.on("shown.bs.modal", function () { 189 availabilityNotificationAfterShown(productModal); 190 }); 191 productModal.on("hide.bs.modal", function () { 192 productModal.remove(); 193 $("#iqitsizecharts-modal").remove(); 194 }); 195 } else { 196 availabilityNotificationAfterShown(productModal); 197 } 198 199 let sizeChartModal = $("#iqitsizecharts-modal");
200 let $productCover; 201 202 productModal.find("#quantity_wanted").TouchSpin({ 203 verticalbuttons: true, 204 verticalupclass: "fa fa-angle-up touchspin-up", 205 verticaldownclass: "fa fa-angle-down touchspin-down", 206 buttondown_class: "btn btn-touchspin js-touchspin", 207 buttonup_class: "btn btn-touchspin js-touchspin", 208 min: 1, 209 max: 1000000, 210 }); 211 212 sizeChartModal.on("show.bs.modal", function () { 213 sizeChartModal.detach(); 214 sizeChartModal.appendTo("body"); 215 $(this).addClass("fv-modal-stack"); 216 productModal.addClass("availabilitynotification-second-modal"); 217 }); 218 }; 219 220 // fin notificacións 221 222 prestashop.on("updatedCart", function (event) { 223 if (event.resp.allRequired != "undefined") { 224 if (event.resp.allRequired == 0) { 225 $(".checkout.cart-detailed-actions.card-body div a").addClass( 226 "disabled", 227 ); 228 } else { 229 $(".checkout.cart-detailed-actions.card-body div a").removeClass( 230 "disabled", 231 ); 232 } 233 } 234 if (event.resp.productQuantities != "undefined") { 235 var productQuantities = event.resp.productQuantities; 236 var elemento = ""; 237 for (indice in event.resp.productQuantities) { 238 elemento = $( 239 '[data-product-id="' + 240 productQuantities[indice].id_product + 241 '"][data-id-product-attribute="' + 242 productQuantities[indice].id_product_attribute + 243 '"]', 244 ); 245 if (elemento.val() > productQuantities[indice].max_quantity) { 246 elemento.val(productQuantities[indice].max_quantity); 247 248 var eventData = { 249 eventType: "updateCart", 250 reason: { 251 idProductAttribute: 252 productQuantities[indice].id_product_attribute, 253 productId: productQuantities[indice].id_product, 254 downUrl: elemento.data("down-url"), 255 upUrl: elemento.data("up-url"), 256 updateUrl: elemento.data("update-url"), 257 }, 258 }; 259 prestashop.emit("updateCart", eventData); 260 } 261 } 262 } 263 }); 264 265 // Novo buscador 266 let initAutocompleteDistr = ( 267 $searchWidgetDistr, 268 $searchBoxDistr, 269 searchURLDistr, 270 ) => { 271 let xhr; 272 // let resultsPerPage = 100000; 273 let resultsPerPage = 15; 274 let allText = $searchBoxDistr.data("all-text"); 275 let productText = $searchBoxDistr.data("product-text"); 276 277 let iqitSearchAutocompleteDistr = $searchBoxDistr.autoCompleteDistr({ 278 minChars: 2, 279 cache: false, 280 source: function (query, response) { 281 try { 282 xhr.abort(); 283 } catch (e) {} 284 xhr = $.post( 285 searchURLDistr, 286 { 287 s: query, 288 resultsPerPage: resultsPerPage, 289 ajax: true, 290 }, 291 null, 292 "json", 293 ) 294 .then(function (resp) { 295 let renderProducts = [ 296 { view: resp.rendered_products_ajax, type: "list" }, 297 ]; 298 299 let showAll = { type: "all" }; 300 if (resp.products.length >= resultsPerPage) { 301 renderProducts.push(showAll); 302 } 303 304 response(renderProducts); 305 // response(resp.rendered_products_ajax); 306 }) 307 .fail(response); 308 }, 309 renderItem: function (rendered_products_ajax, search) { 310 if (rendered_products_ajax.type == "all") { 311 return ( 312 '<div class="row btn-all">' + 313 '<div class="autocomplete-suggestion autocomplete-suggestion-show-all dropdown-item" data-type="all" data-val="' + 314 search + 315 '">' + 316 '<div class="row no-gutters align-items-center">' + 317 '<div class="col"><span class="name">' + 318 allText + 319 ' <i class="fa fa-angle-right" aria-hidden="true"></i></span></div>' + 320 "</div>" + 321 "</div>" + 322 "</div>" 323 ); 324 } else { 325 return rendered_products_ajax.view; 326 } 327 328 // return rendered_products_ajax; 329 }, 330 onSelect: function (e, term, item) { 331 if (item.data("type") == "all") { 332 $searchWidgetDistr.find("form").first().submit(); 333 } else { 334 window.location.href = item.data("url"); 335 } 336 }, 337 }); 338 }; 339 340 // antigo buscador 341 let initAutocomplete = ($searchWidget, $searchBox, searchURL) => { 342 let xhr; 343 let resultsPerPage = 10; 344 let allText = $searchBox.data("all-text"); 345 let brandsText = $searchBox.data("brands-text"); 346 let productText = $searchBox.data("product-text"); 347 let blogText = $searchBox.data("blog-text"); 348 349 let iqitSearchAutocomplete = $searchBox.autoComplete({ 350 minChars: 2, 351 cache: false, 352 source: function (query, response) { 353 try { 354 xhr.abort(); 355 } catch (e) {} 356 xhr = $.post( 357 searchURL, 358 { 359 s: query, 360 resultsPerPage: resultsPerPage, 361 ajax: true, 362 }, 363 null, 364 "json", 365 ) 366 .then(function (resp) { 367 if (Object.keys(resp.brands).length) { 368 let brands = { type: "brands", results: resp.brands }; 369 resp.products.push(brands); 370 } 371 if (Object.keys(resp.blogposts).length) { 372 let posts = { type: "posts", results: resp.blogposts }; 373 resp.products.push(posts); 374 } 375 let showAll = { type: "all" }; 376 if (resp.products.length >= resultsPerPage) { 377 resp.products.push(showAll); 378 } 379 response(resp.products); 380 }) 381 .fail(response); 382 }, 383 renderItem: function (product, search) { 384 if (product.type == "all") { 385 return ( 386 '<div class="autocomplete-suggestion autocomplete-suggestion-show-all dropdown-item" data-type="all" data-val="' + 387 search + 388 '">' + 389 '<div class="row no-gutters align-items-center">' + 390 '<div class="col"><span class="name">' + 391 allText + 392 ' <i class="fa fa-angle-right" aria-hidden="true"></i></span></div>' + 393 "</div>" + 394 "</div>" 395 ); 396 } else if (product.type == "brands") { 397 let brandsHtml = ""; 398
399 Object.keys(product.results).forEach(function (key) { 400 brandsHtml += 401 '<div class="autocomplete-suggestion dropdown-item" data-url="' + 402 product.results[key].link + 403 '">' + 404 '<div class="row no-gutters align-items-center">' + 405 '<div class="col col-auto col-img"><img class="img-fluid" src="' + 406 product.results[key].image + 407 '" /></div>' + 408 '<div class="col pt-3 pb-3"><span class="name">' + 409 product.results[key].name + 410 "</span></div>" + 411 '<div class="col col-auto col-shop pt-3 pb-3 ">' + 412 brandsText + 413 "</div>" + 414 "</div></div>"; 415 }); 416 return brandsHtml; 417 } else if (product.type == "posts") { 418 let postsHtml = ""; 419 420 Object.keys(product.results).forEach(function (key) { 421 let imageHtml = ""; 422 if (typeof product.results[key].banner_thumb !== "undefined") { 423 imageHtml = 424 '<img class="img-fluid" src="' + 425 product.results[key].banner_thumb + 426 '" />'; 427 } 428 429 postsHtml += 430 '<div class="autocomplete-suggestion dropdown-item" data-url="' + 431 product.results[key].url + 432 '">' + 433 '<div class="row no-gutters align-items-center">' + 434 '<div class="col col-auto col-img"><div class="col col-auto col-img">' + 435 imageHtml + 436 "</div></div>" + 437 '<div class="col pt-3 pb-3"><span class="name">' + 438 product.results[key].title + 439 "</span></div>" + 440 '<div class="col col-auto col-shop pt-3 pb-3 ">' + 441 blogText + 442 "</div>" + 443 "</div></div>"; 444 }); 445 return postsHtml; 446 } else { 447 let imageHtml = ""; 448 let addCart = ""; 449 450 if (product.id_manufacturer == 156) { 451 addCart = 452 '<a href="' + 453 product.canonical_url + 454 '" class="btn btn-product-list add-to-cart ' + 455 product.quantity + 456 '">' + 457 '<span class="sin-stock" style="">' + 458 product.add_to_cart_labels.stock + 459 "</span>" + 460 "</a>"; 461 } else { 462 if (product.quantity > 0) { 463 addCart = 464 '<a style="z-index:99999;"href="' + 465 product.add_to_cart_url + 466 '" class="btn btn-product-list add-to-cart ' + 467 product.quantity + 468 '">' + 469 '<span class="sin-stock" style="">' + 470 product.add_to_cart_labels.stock + 471 "</span>" + 472 "</a>"; 473 } else { 474 addCart = 475 '<a href="' + 476 product.canonical_url + 477 '" class="btn btn-product-list no-stock ' + 478 product.quantity + 479 '">' + 480 '<span class="sin-stock" style="">' + 481 product.add_to_cart_labels.no_stock + 482 "</span>" + 483 "</a>"; 484 } 485 } 486 487 try { 488 imageHtml = 489 '<div class="col col-auto col-img"><img class="img-fluid" src="' + 490 product.cover.small.url + 491 '" /></div>'; 492 } catch (e) { 493 imageHtml = ""; 494 } 495 496 // prezo unitario 497 let product_price = product.price; 498 if (product.unit_price) product_price = product.unit_price; 499 500 // produtos resaltados 501 let product_resaltado = ""; 502 if (product.hasOwnProperty("resaltado")) 503 product_resaltado = "product-resaltado"; 504 505 return ( 506 // '<div class="autocomplete-suggestion dropdown-item" data-url="' + 507 // product.url + 508 // '">' + 509 // '<div class="row no-gutters align-items-center">' + 510 // imageHtml + 511 // '<div class="col pt-3 pb-3"><span class="name">' + 512 // product.name + 513 // '</span><span class="product-price">' + 514 // product.price + 515 // "</span></div>" + 516 // '<div class="col col-auto col-shop pt-3 pb-3 ">' + 517 // addCart + 518 // "</div>" + 519 // "</div>" + 520 // "</div>" 521 '<div class="row dropdown-item ' + 522 product_resaltado + 523 '" style="display: flex;padding: 0;margin: 0;width:100%;">
523' + 524 '<div class="autocomplete-suggestion col col-7 pt-3 pb-3" data-url="' + 525 product.url + 526 '">' + 527 '<div class="row no-gutters align-items-center">' + 528 imageHtml + 529 '<div class="col pt-3 pb-3"><span class="name">' + 530 product.name + 531 '</span><span class="product-price">' + 532 // product.price + 533 product_price + 534 "</span></div>" + 535 "</div>" + 536 "</div>" + 537 '<div class="col col-auto col-shop pt-3 pb-3" style="align-self: center;">' + 538 addCart + 539 "</div>" + 540 "</div>" 541 ); 542 } 543 }, 544 onSelect: function (e, term, item) { 545 if (item.data("type") == "all") { 546 $searchWidget.find("form").submit(); 547 } else { 548 window.location.href = item.data("url"); 549 } 550 }, 551 }); 552 }; 553 554 let $searchWidgetDistr = $("#search_widget_distr"); 555 let $searchBoxDistr = $searchWidgetDistr.find("input[type=text]"); 556 let searchURLDistr = $searchWidgetDistr.attr("data-search-controller-url"); 557 let $searchToggleDistr = $("#header-search-btn"); 558 559 initAutocompleteDistr($searchWidgetDistr, $searchBoxDistr, searchURLDistr); 560 561 let $searchWidgetMobile = $("#search-widget-mobile"); 562 let $searchBoxMobile = $searchWidgetMobile.find("input[type=text]"); 563 let $searchToggleMobile = $("#mobile-btn-search"); 564 565 initAutocomplete($searchWidgetMobile, $searchBoxMobile, searchURLDistr); 566 567 $searchToggleDistr.on("shown.bs.dropdown", function () { 568 setTimeout(function () { 569 $searchBoxDistr.focus(); 570 }, 300); 571 }); 572 573 $searchToggleMobile.on("shown.bs.dropdown", function () { 574 setTimeout(function () { 575 $("#mobile-btn-search").find("input[type=text]").focus(); 576 }, 300); 577 }); 578 579 $("#fullscreen-search-backdrop").on("touchstart", function (e) { 580 e.stopPropagation(); 581 $("#header-search-btn-drop").dropdown("toggle"); 582 }); 583}); 584 585(function ($) { 586 $.fn.autoCompleteDistr = function (options) { 587 var o = $.extend({}, $.fn.autoComplete.defaults, options); 588 589 // public methods 590 if (typeof options == "string") { 591 this.each(function () { 592 var that = $(this); 593 if (options == "destroy") { 594 // that.off('blur.autocomplete focus.autocomplete keydown.autocomplete keyup.autocomplete'); 595 that.off("blur.autocomplete focus.autocomplete keyup.autocomplete"); 596 if (that.data("autocomplete")) 597 that.attr("autocomplete", that.data("autocomplete")); 598 else that.removeAttr("autocomplete"); 599 $(that.data("sc")).remove(); 600 that.removeData("sc").removeData("autocomplete"); 601 } 602 }); 603 return this; 604 } 605 606 return this.each(function () { 607 var that = $(this); 608 // sc = 'suggestions container' 609 610 that.sc = $( 611 '<div class="autocomplete-suggestions ' + o.menuClass + '"></div>', 612 ); 613 that.data("sc", that.sc).data("autocomplete", that.attr("autocomplete")); 614 that.attr("autocomplete", "off"); 615 that.cache = {}; 616 that.last_val = ""; 617 618 that.updateSC = function (resize, next) { 619 that.sc.show(); 620 }; 621 622 that.sc.insertAfter(that.parent().parent()); 623 624 that.siblings(".clear-btn").on("click", function () { 625 that.val(""); 626 that.trigger("keyup.autocomplete"); 627 $(this).hide(); 628 }); 629 630 that.sc.on("mouseleave", ".autocomplete-suggestion", function () { 631 $(".autocomplete-suggestion.selected").removeClass("selected"); 632 }); 633 634 that.sc.on("mouseenter", ".autocomplete-suggestion", function () { 635 $(".autocomplete-suggestion.selected").removeClass("selected"); 636 $(this).addClass("selected"); 637 }); 638 639 that.sc.on("mousedown click", ".autocomplete-suggestion", function (e) { 640 var item = $(this), 641 v = item.data("val"); 642 if (v || item.hasClass("autocomplete-suggestion")) { 643 // else outside click 644 that.val(v); 645 o.onSelect(e, v, item); 646 that.sc.hide(); 647 } 648 return false;
649 }); 650 651 that.on("blur.autocomplete", function () { 652 var val = that.val(); 653 if (val.length < o.minChars) { 654 that.sc.hide(); 655 } 656 }); 657 658 if (!o.minChars) 659 that.on("focus.autocomplete", function () { 660 that.last_val = "\n"; 661 that.trigger("keyup.autocomplete"); 662 }); 663 664 function suggest(data) { 665 var val = that.val(); 666 that.cache[val] = data; 667 if (data.length && val.length >= o.minChars) { 668 var s = ""; 669 for (var i = 0; i < data.length; i++) s += o.renderItem(data[i], val); 670 that.sc.html(s); 671 that.updateSC(0); 672 } else { 673 that.sc.hide(); 674 } 675 } 676 677 // that.on('keydown.autocomplete', function(e){ 678 // // down (40), up (38) 679 // if ((e.which == 40 || e.which == 38) && that.sc.html()) { 680 // var next, sel = $('.autocomplete-suggestion.selected', that.sc); 681 // if (!sel.length) { 682 // next = (e.which == 40) ? $('.autocomplete-suggestion', that.sc).first() : $('.autocomplete-suggestion', that.sc).last(); 683 // that.val(next.addClass('selected').data('val')); 684 // } else { 685 // next = (e.which == 40) ? sel.next('.autocomplete-suggestion') : sel.prev('.autocomplete-suggestion'); 686 // if (next.length) { sel.removeClass('selected'); that.val(next.addClass('selected').data('val')); } 687 // else { sel.removeClass('selected'); that.val(that.last_val); next = 0; } 688 // } 689 // that.updateSC(0, next); 690 // return false; 691 // } 692 // // esc 693 // else if (e.which == 27){ that.val(that.last_val).sc.hide();console.log("hide -> keydown.autocomplete 1");} 694 // // enter or tab 695 // else if (e.which == 13 || e.which == 9) { 696 // var sel = $('.autocomplete-suggestion.selected', that.sc); 697 // if (sel.length && that.sc.is(':visible')) { o.onSelect(e, sel.data('val'), sel); setTimeout(function(){ that.sc.hide(); console.log("hide -> keydown.autocomplete 2");}, 20); } 698 // } 699 // }); 700 701 that.on("keyup.autocomplete", function (e) { 702 if (!~$.inArray(e.which, [13, 27, 35, 36, 37, 38, 39, 40])) { 703 var val = that.val(); 704 if (val.length > 0) { 705 that.siblings(".clear-btn").show(); 706 } 707 if (val.length >= o.minChars) { 708 if (val != that.last_val) { 709 that.last_val = val; 710 clearTimeout(that.timer); 711 if (o.cache) { 712 if (val in that.cache) { 713 suggest(that.cache[val]); 714 return; 715 } 716 // no requests if previous suggestions were empty 717 for (var i = 1; i < val.length - o.minChars; i++) { 718 var part = val.slice(0, val.length - i); 719 if (part in that.cache && !that.cache[part].length) { 720 suggest([]); 721 return; 722 } 723 } 724 } 725 that.timer = setTimeout(function () { 726 o.source(val, suggest); 727 }, o.delay); 728 } 729 } else { 730 that.last_val = val; 731 that.sc.hide(); 732 } 733 } 734 }); 735 }); 736 }; 737 738 $.fn.autoCompleteDistr.defaults = { 739 source: 0, 740 minChars: 2, 741 delay: 150, 742 cache: 1, 743 menuClass: "", 744 renderItem: function (item, search) { 745 // escape special characters 746 search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); 747 var re = new RegExp("(" + search.split(" ").join("|") + ")", "gi"); 748 return ( 749 '<div class="autocomplete-suggestion" data-val="' + 750 item + 751 '">' + 752 item.replace(re, "<b>$1</b>") + 753 "</div>" 754 ); 755 }, 756 onSelect: function (e, term, item) {}, 757 }; 758})(jQuery); 759 760// KZdev: novo proceso de pedido -> resumo 761(function ($) { 762 $(document).ready(() => { 763 updatedCartSpin(); 764 765 if (typeof prestashop !== "undefined") { 766 prestashop.cart = prestashop.cart || {}; 767 // Refresh cart preview 768 prestashop.on("updateCart", function () { 769 if (prestashop.page.page_name === "checkout") { 770 location.reload(); 771 } 772 }); 773 } 774 }); 775 776 function updatedCartSpin() { 777 $(
778 'body#checkout .cart-item.cart-summary-product input[name="product-quantity-spin"]', 779 ).each(function () { 780 if ($(this).TouchSpin().val() == 1) { 781 var button_icon = document.createElement("i"); 782 button_icon.setAttribute("class", "fa fa-trash-o"); 783 $(this).parent().children(":first").children("button").empty(); 784 $(this) 785 .parent() 786 .children(":first") 787 .children("button") 788 .append(button_icon); 789 } 790 }); 791 } 792})(jQuery); 793 794/* ---------------------------OS--------------------------------- */ 795 796/* -------------------------------------------------------------- */ 797// OS 798 799$(document).ready(function () { 800 /** 801 * Regex prefijo 802 */ 803 804 /** 805 * Main Menu Expand 806 */ 807 let mainMenuExpand = false; 808 809 $("#header .ce-btn-main-menu-expand").on("click", function () { 810 const icon = $(".ce-btn-main-menu-expand .elementor-icon i.ceicon"); 811 const header = $("#header"); 812 813 if (!mainMenuExpand) { 814 // Expandir el menú 815 mainMenuExpand = true; 816 icon.removeClass("ceicon-burger").addClass("ceicon-close"); 817 header[0].style.setProperty("margin-top", "-90px", "important"); // Ajusta el margin-top 818 } else { 819 // Contraer el menú 820 mainMenuExpand = false; 821 icon.removeClass("ceicon-close").addClass("ceicon-burger"); 822 header[0].style.setProperty("margin-top", "-140px", "important"); // Restablece el margin-top 823 } 824 }); 825 826 /** 827 * Main Menu Responsive 828 */ 829 $("#menu-responsive").on("click", function () { 830 // Alternar la clase 'elementor-active' en el botón de menú 831 $(this).toggleClass("elementor-active"); 832 833 // Verificar si el menú está activo 834 if ($(this).hasClass("elementor-active")) { 835 // Añadir el Ãcono "X" al menú si está activo 836 $(this).find("ul.elementor-nav").find(".menu-close-icon").remove(); // Evitar duplicados 837 $(this) 838 .find("ul.elementor-nav") 839 .prepend('<li class="menu-close-icon">â</li>'); 840 841 // Bloquear el scroll 842 $("body").css("overflow", "hidden"); 843 } else { 844 // Quitar el Ãcono "X" si el menú se cierra 845 $(this).find("ul.elementor-nav").find(".menu-close-icon").remove(); 846 847 // Restaurar el scroll 848 $("body").css("overflow", ""); 849 } 850 }); 851 852 // Funcionalidad para cerrar el menú al hacer clic en la "X" 853 $(document).on("click", ".menu-close-icon", function (event) { 854 // Prevenir que el clic en la "X" también dispare el evento del botón principal 855 event.stopPropagation(); 856 857 // Eliminar la clase .elementor-active del contenedor del menú 858 $("#menu-responsive").removeClass("elementor-active"); 859 860 // Quitar el Ãcono "X" 861 $(this).closest("ul.elementor-nav").find(".menu-close-icon").remove(); 862 863 // Restaurar el scroll 864 $("body").css("overflow", ""); 865 }); 866 867 /** 868 * Trigger para detectar cuando el scroll está en el top y cuando se hace scroll hacia abajo. 869 */ 870 let hasScrolledDown = false; // Bandera para detectar el primer scroll hacia abajo 871 872 $(window).on("scroll", function () { 873 const header = $("#header"); 874 const icon = $(".ce-btn-main-menu-expand .elementor-icon i.ceicon"); 875 const body = $("body"); 876 const windowWidth = $(window).width(); // Obtener el ancho de la ventana 877 878 // Si el scroll está en el top (scrollTop === 0) 879 if ($(window).scrollTop() === 0) { 880 // Cuando estamos al top, restablecer el margin-top del header a 0px 881 mainMenuExpand = false; 882 icon.removeClass("ceicon-close").addClass("ceicon-burger"); // Resetear el icono 883 884 // Ajustar el margin-top del header 885 header[0].style.setProperty("margin-top", "0px", "important"); // Ajustar margin-top a 0px 886 887 // Si el body tiene la clase 'stick_menu_displayed', la mantenemos 888 if (body.hasClass("stick_menu_displayed")) { 889 // Se mantiene la propiedad de la clase stick_menu_displayed 890 // No cambiamos nada, solo dejamos que la clase siga aplicando esos estilos. 891 } 892 893 // Resetear la bandera de scroll hacia abajo 894 hasScrolledDown = false; 895 } else if (!hasScrolledDown) { 896 // Si el scroll ha bajado por primera vez, aplicar la clase 'stick_menu_displayed' 897 body.addClass("stick_menu_displayed"); // Agregar la clase stick_menu_displayed al body 898 899 // Ajustar el margin-top cuando se desciende, dependiendo del tamaño de la ventana 900 if (windowWidth <= 768) { 901 header[0].style.setProperty("margin-top", "0px", "important"); // Ajustar margin-top a 0px en pantallas pequeñas 902 } else { 903 header[0].style.setProperty("margin-top", "-140px", "important"); // Ajustar margin-top a -140px en pantallas grandes 904 } 905 906 // Marcar que el scroll hacia abajo ya ha sucedido 907 hasScrolledDown = true; 908 } 909 }); 910 911 /** 912 * Megamenú 913 */ 914 function updateMenuContent(element) { 915 //Pintar el menú en la ventana del mega menú 916 const htmlContent = element.find(".cbp-category-tree").html(); 917 const linkText = element.find("a.cbp-column-title").text(); 918 // Verificar si htmlContent está vacÃo 919 if (!htmlContent) { 920 return; // No hacer nada si htmlContent está vacÃo 921 } 922 const newContent = `<p class="category-name">${linkText}</p>${htmlContent}`; 923 const targetDiv = $( 924 "#iqitmegamenu-horizontal .col-8.cbp-menu-column.cbp-menu-element > .cbp-menu-column-inner > div:nth-child(2) > .cbp-menu-column", 925 ); 926 targetDiv.html(newContent); 927 } 928 929 // Función para actualizar el href 930 function actualizarHrefPorHover(elemento) { 931 setTimeout(function () { 932 const titulo = $(".iqitmegamenu .col-8 .category-name:first") 933 .text() 934 .trim(); 935 const matchingLink = $(elemento) 936 .find("a.cbp-category-title") 937 .filter(function () { 938 return $(this).text().trim() === titulo; 939 }); 940 if (matchingLink.length > 0) { 941 const nuevoHref = matchingLink.attr("href"); 942 $(".iqitmegamenu .col-8 .menu_row .cbp-menu-column p a").attr( 943 "href", 944 nuevoHref, 945 ); 946 } 947 }, 200); 948 } 949 950 /** 951 * Megamenú actualizar href manuales 952 */ 953 function actualizarHrefManuales() { 954 $(".cbp-category-link-w").each(function () { 955 var textoElemento = $(this).text().trim().toLowerCase(); 956 var textosHref = { 957 "manuales y despieces": 958 "https://distribucionmayorista.online/es/content/14-manuales", 959 "manuals and exploded views": 960 "https://distribucionmayorista.online/en/content/14-manuales", 961 manuels: "https://distribucionmayorista.online/fr/content/14-manuales", 962 manuais: "https://distribucionmayorista.online/pt/content/14-manuales", 963 "handbücher und teile": 964 "https://distribucionmayorista.online/de/content/14-manuales", 965 }; 966 967 if (textosHref[textoElemento]) { 968 $(this).find("a").attr("href", textosHref[textoElemento]); 969 /* console.log($(this)); */ 970 } 971 }); 972 } 973 actualizarHrefManuales(); 974 975 $( 976 ".iqitmegamenu .cbp-hrsub, .iqitmegamenu .iqitmegamenu-submenu-container .cbp-category-link-w", 977 ).hover(function () { 978 actualizarHrefPorHover(this); 979 }); 980 981 $("#iqitmegamenu-wrapper .cbp-hrmenu-tab").on("mouseenter", function () { 982 const firstItem = $(this).find(".cbp-category-link-w").first(); 983 updateMenuContent(firstItem); 984 }); 985 986 $("#iqitmegamenu-wrapper .cbp-category-link-w").on("mouseenter", function () { 987 $("#iqitmegamenu-wrapper .cbp-category-link-w").removeClass( 988 "underline-hover", 989 ); 990 $(this).addClass("underline-hover"); 991 updateMenuContent($(this)); 992 }); 993 994 $("#iqitmegamenu-wrapper").on("mouseleave", function () { 995 $("#iqitmegamenu-wrapper .cbp-category-link-w").removeClass( 996 "underline-hover", 997 ); 998 }); 999 1000 // Ejecutar la función cuando la página cargue 1001 window.onload = actualizarHrefManuales; 1002 1003 // Llamar a la función cuando la página haya cargado 1004 window.onload = actualizarHrefManuales; 1005 1006 /** 1007 * Megamenú Marcas - Ordenar marcas por orden alfabético y añadir enlaces dinámicos con idioma en URL 1008 */ 1009 $("#cbp-hrmenu-tab-27 .cbp-menu-column").each(function () {
1010 let currentLetter = ""; 1011 let letterCount = 0; 1012 1013 // Obtener el idioma actual desde la URL (por ejemplo, '/es/', '/fr/', etc.) 1014 const currentLanguage = window.location.pathname.split("/")[1]; 1015 1016 // Definir la ruta correspondiente a marcas según el idioma 1017 let brandsPath = "marcas"; 1018 if (currentLanguage === "fr" || currentLanguage === "pt") { 1019 brandsPath = "brands"; 1020 } else if (currentLanguage === "de") { 1021 brandsPath = "verkaufsprodukte-der-besten-marken-grosshandelsvertrieb"; 1022 } 1023 1024 $(this) 1025 .find("ul.cbp-links li") 1026 .each(function () { 1027 const brandName = $(this).text().trim(); 1028 const brandNameUpper = brandName.toUpperCase(); 1029 const firstLetter = brandNameUpper.charAt(0); 1030 1031 const allowedBrands = [ 1032 "ALIVE", 1033 "AQUARIUS", 1034 "ARRUABARRENA", 1035 "ARTIACH - CUÃTARA", 1036 "BIMBO-MARTINEZ", 1037 "BRETS", 1038 "CASAMAYOR", 1039 "CHEETOS", 1040 "CHOCOLATES VALOR", 1041 "CHUPA CHUPS", 1042 "CLIPPER", 1043 "COCACOLA", 1044 "CONTROL", 1045 "CUÃTARA", 1046 "CUEVAS", 1047 "DAMEL", 1048 "DON SIMON", 1049 "DULCESOL", 1050 "DUREX", 1051 "ELGORRIAGA", 1052 "ENERYETI", 1053 "FACUNDO", 1054 "FERRERO KINDER", 1055 "FILIPINOS", 1056 "FINI", 1057 "GRANINI", 1058 "GREFUSA", 1059 "GULLON", 1060 "HALLS", 1061 "HARIBO", 1062 "HERO", 1063 "HUESITOS", 1064 "JOFEMAR", 1065 "JUICY JAY'S", 1066 "KAS", 1067 "KELIA", 1068 "KELLOGG´S", 1069 "KIT KAT", 1070 "LA BATURRICA", 1071 "LACASA", 1072 "LAYS", 1073 "LIPTON", 1074 "LU", 1075 "MARS", 1076 "MATUTANO", 1077 "MENTOS", 1078 "MILKA", 1079 "MONDELEZ", 1080 "MONSTER", 1081 "NESCAFE", 1082 "NESTEA", 1083 "NESTLE", 1084 "OCB", 1085 "ORBIT", 1086 "OREO", 1087 "PASCUAL", 1088 "PEPSICO", 1089 "PRESTIGE", 1090 "PRINGLES", 1091 "QÃ", 1092 "RAW", 1093 "REDBULL", 1094 "REESE´S", 1095 "REGILAIT", 1096 "ROCKSTAR", 1097 "RUFFLES", 1098 "SAIMAZA", 1099 "SAN BENEDETTO", 1100 "SANDEN VENDO", 1101 "SATISFYER", 1102 "SIMAT", 1103 "SMOKING", 1104 "TORO LOCO", 1105 "TOSFRIT", 1106 "TOY JOY", 1107 "TRIDENT", 1108 "VELARTE", 1109 "VIDAL GOLOSINAS", 1110 "VIGAREX FORTE", 1111 "VILLA", 1112 "WERTHER'S", 1113 ]; 1114 1115 if (!allowedBrands.includes(brandNameUpper)) { 1116 $(this).remove(); 1117 return; 1118 } 1119 1120 if (firstLetter !== currentLetter) {
1121 currentLetter = firstLetter; 1122 $(this).before( 1123 `<li><span class="capital-letter" data-letter="${currentLetter}" style="cursor: pointer;">${currentLetter}.</span></li>`, 1124 ); 1125 } 1126 }); 1127 1128 // Añadir funcionalidad de click en la letra 1129 $(".capital-letter").on("click", function () { 1130 const letter = $(this).data("letter"); 1131 const url = `https://distribucionmayorista.online/${currentLanguage}/${brandsPath}#man-letter-${letter.toUpperCase()}`; 1132 1133 /* console.log("Guardando en localStorage la letra:", letter); */ 1134 localStorage.setItem("selectedLetter", letter.toUpperCase()); 1135 1136 window.location.href = url; // Redirigir a la URL con la ancla 1137 }); 1138 }); 1139 1140 // Aplicar el efecto de scroll tras la redirección 1141 window.onload = function () { 1142 /* console.log("Se ha iniciado el onload"); */ 1143 1144 const letter = localStorage.getItem("selectedLetter"); 1145 /* console.log("Letra recuperada de localStorage:", letter); */ 1146 1147 if (letter) { 1148 // Construimos el selector con la letra recuperada 1149 const targetAnchor = `#man-letter-${letter}`; 1150 /* console.log("targetAnchor:", targetAnchor); */ 1151 1152 // Prevenir el comportamiento de scroll automático al hacer la redirección 1153 if (window.location.hash === targetAnchor) { 1154 // Evitar que el navegador haga el scroll automático 1155 history.replaceState(null, null, window.location.href.split("#")[0]); 1156 } 1157 1158 // Buscar el elemento con el atributo `name` correspondiente 1159 const targetElement = document.querySelector( 1160 `a[name="man-letter-${letter}"]`, 1161 ); 1162 /* console.log("Elemento encontrado:", targetElement ? "SÃ" : "No"); */ 1163 1164 if (targetElement) { 1165 /* console.log("ENTRA POR AQUI??"); */ 1166 // Obtener la posición del elemento en la página 1167 const elementPosition = 1168 targetElement.getBoundingClientRect().top + window.scrollY; 1169 const menuHeight = document.querySelector(".menu")?.offsetHeight || 100; // Ajusta la altura del menú fijo 1170 1171 // Realizar el scroll con desplazamiento inmediato 1172 window.scrollTo({ 1173 top: elementPosition - menuHeight + 100, // Ajuste para no quedar tapado por el menú fijo 1174 behavior: "smooth", // Desplazamiento suave 1175 }); 1176 1177 // Eliminar la letra del localStorage después de realizar la acción 1178 localStorage.removeItem("selectedLetter"); 1179 } else { 1180 console.warn("No se encontró el destino del enlace:", targetAnchor); 1181 } 1182 } 1183 }; 1184 1185 /** 1186 * Quitar href menu Marcas 1187 */ 1188 $("#cbp-hrmenu-tab-27 > a").removeAttr("href"); 1189 1190 /** 1191 * Página Marcas - Ordenar marcas por orden alfabético 1192 */ 1193 $("#brand-mod").each(function () {
1194 let currentLetter = ""; 1195 1196 $(this) 1197 .find("ul .facet-label") 1198 .each(function () { 1199 const brandName = $(this).text().trim(); 1200 const firstLetter = brandName.charAt(0).toUpperCase(); 1201 1202 // Solo agregar el encabezado de letra si es una letra diferente 1203 if (firstLetter !== currentLetter) { 1204 currentLetter = firstLetter; 1205 $(this).before( 1206 `<li><span class="capital-letter">${currentLetter}.</span></li>`, 1207 ); 1208 } 1209 }); 1210 }); 1211 1212 /** 1213 * Añadir Ofertas Vending al menú lateral de la página de Ofertas 1214 */ 1215 function addVendingOffersMenuItem() { 1216 const siteUrl = document.location.origin; 1217 const lang = $("html").attr("lang"); 1218 const translations = { 1219 es: { text: "Ofertas Vending", href: "/es/255-ofertas-vending" }, 1220 fr: { text: "Offres Vending", href: "/fr/255-offres" }, 1221 pt: { text: "Ofertas Vending", href: "/pt/255-ofertas" }, 1222 en: { text: "Vending Offers", href: "/en/255-offers" }, 1223 de: { text: "Vending-Angebote", href: "/de/255-verkaufsangebote" }, 1224 }; 1225 const { text, href } = translations[lang] || translations["es"]; 1226 const imageUrl = 1227 siteUrl + "/themes/warehousechild/assets/img/icono_flame.png"; 1228 1229 $("#menu-lateral-ofertas ul").append( 1230 '<li class="menu-item menu-item-type-custom">' + 1231 '<a class="elementor-item" href=' + 1232 href + 1233 ">" + 1234 '<img class="cat-menu" src=' + 1235 imageUrl + 1236 ' alt="' + 1237 text + 1238 '">' + 1239 text + 1240 "</a>" + 1241 "</li>", 1242 ); 1243 } 1244 1245 addVendingOffersMenuItem(); 1246 1247 function menuResetInputValue() { 1248 const input = $("div.zomlmm input"); 1249 input.val(""); 1250 } 1251 menuResetInputValue(); 1252 1253 $(function () { 1254 var menu = $("#header"); // Reemplaza con la clase real de tu menú 1255 var menuHeight = menu.length ? menu.outerHeight() : 80; // Detecta la altura del menú, usa 80px por defecto 1256 1257 $(".ms-letter-selector a").on("click", function (event) { 1258 event.preventDefault(); // Evita el salto brusco 1259 1260 var targetId = $(this).attr("href").substring(1); // Obtiene el ID sin # 1261 var targetElement = $(`[name="${targetId}"]`); 1262 1263 if (targetElement.length) { 1264 var elementPosition = targetElement.offset().top; 1265 1266 $("html, body").animate( 1267 { 1268 scrollTop: elementPosition - menuHeight + 100, // Offset para compensar el menú 1269 }, 1270 100, 1271 ); // Duración del scroll en milisegundos (ajústalo según necesites) 1272 } 1273 }); 1274 }); 1275 1276 $(document).ready(function () { 1277 // Función para modificar el contenido de .menu-element-id-19 1278 function actualizarContenido() { 1279 var $ulLink = $(".menu-element-id-22 ul.cbp-links li a").first(); 1280 if ($ulLink.length) { 1281 var newUrl = $ulLink.attr("href"); 1282 var newText = $ulLink.text(); 1283 var $img = $ulLink 1284 .closest("li") 1285 .find("a") 1286 .not($ulLink) 1287 .find("img") 1288 .first(); 1289 var newImgUrl = $img.length ? $img.attr("src") : ""; 1290 var newImgAlt = $img.length ? $img.attr("alt") : ""; 1291 var $icon = $ulLink.closest("li").find("i").first(); 1292 var newIcon = $icon.length ? $icon.clone() : null; 1293 1294 var $targetBlock = $( 1295 ".menu-element-id-19 .cbp-categories-row .col-12", 1296 ).eq(1); 1297 if ($targetBlock.length) { 1298 var $titleAnchor = $targetBlock.find("a.cbp-column-title"); 1299 $titleAnchor.attr("href", newUrl).text(newText); 1300 if (newIcon && !$titleAnchor.next("i").length) { 1301 $titleAnchor.after(newIcon); 1302 } 1303 var $thumbAnchor = $targetBlock.find("a.cbp-category-thumb"); 1304 $thumbAnchor.attr("href", newUrl); 1305 if (newImgUrl) { 1306 $thumbAnchor.find("img").attr("src", newImgUrl); 1307 } 1308 if (newImgAlt) { 1309 $thumbAnchor.find("img").attr("alt", newImgAlt); 1310 } 1311 } 1312 // Eliminar el bloque original 1313 $(".menu-element-id-22").remove(); 1314 } 1315 1316 // Ahora que el contenido ha sido actualizado, ejecutar la función para modificar el menú lateral 1317 actualizarMenuLateral(); 1318 } 1319 1320 // Función para actualizar el menú lateral 1321 function actualizarMenuLateral() { 1322 if ( 1323 $("body").hasClass("page-category") || 1324 $("body").hasClass("page-search") 1325 ) { 1326 $("#menu-lateral-categorias").empty(); 1327 var newContent; 1328 if ( 1329 $("body").is( 1330 ".category-id-parent-142, .category-id-parent-164, .category-id-parent-167", 1331 ) 1332 ) { 1333 newContent = $( 1334 "#cbp-hrmenu-tab-26 .menu-element-id-1 .menu-element-id-2", 1335 ).html(); 1336 } else { 1337 newContent = $(".menu-element-id-1 .menu-element-id-2").html(); 1338 } 1339 $("#menu-lateral-categorias").html(newContent); 1340 } 1341 1342 $("#menu-lateral-categorias .cbp-category-link-w").each(function () { 1343 const $menu = $(this); 1344 const $linkTitle = $menu.find(".cbp-category-title"); 1345 const $linkThumb = $menu.find(".cbp-category-thumb"); 1346 const categoryName = $linkTitle.text().trim(); 1347 const categoryHref = $linkTitle.attr("href"); 1348 const $submenu = $menu 1349 .find(".cbp-category-tree") 1350 .detach() 1351 .insertAfter($menu) 1352 .hide(); 1353 const translations = { 1354 es: "Todo", 1355 fr: "Tout", 1356 pt: "Tudo", 1357 en: "All", 1358 de: "Alle", 1359 }; 1360 const lang = document.documentElement.lang || "es"; 1361 const translatedTodo = translations[lang] || "Todo"; 1362 if ($submenu.length > 0) { 1363 $submenu.prepend(` 1364 <li> 1365 <div class="cbp-category-link-w"> 1366 <a href="${categoryHref}">${translatedTodo} ${categoryName}</a> 1367 </div> 1368 </li> 1369 `); 1370 } 1371 if ($submenu.length > 0) { 1372 const $arrowButton = $( 1373 '<span class="menu-toggle-arrow fas fa-chevron-right"></span>', 1374 ); 1375 $menu.prepend($arrowButton); 1376 const toggleSubmenu = function () { 1377 const isOpen = $submenu.is(":visible"); 1378 $("#menu-lateral-categorias .cbp-category-tree").slideUp(200); 1379 $("#menu-lateral-categorias .menu-toggle-arrow") 1380 .removeClass("fas fa-chevron-down") 1381 .addClass("fas fa-chevron-right"); 1382 $("#menu-lateral-categorias .cbp-category-link-w").removeClass( 1383 "hide-after", 1384 ); 1385 if (isOpen) {
1386 $submenu.stop(true, true).slideUp(300); 1387 $arrowButton 1388 .removeClass("fas fa-chevron-down") 1389 .addClass("fas fa-chevron-right"); 1390 } else { 1391 $submenu.stop(true, true).slideDown(300); 1392 $arrowButton 1393 .removeClass("fas fa-chevron-right") 1394 .addClass("fas fa-chevron-down"); 1395 $menu.addClass("hide-after"); 1396 } 1397 }; 1398 $arrowButton.on("click", toggleSubmenu); 1399 $linkTitle.on("click", function (e) { 1400 e.preventDefault(); 1401 toggleSubmenu(); 1402 }); 1403 $linkThumb.on("click", function (e) { 1404 e.preventDefault(); 1405 toggleSubmenu(); 1406 }); 1407 } 1408 }); 1409 1410 // Después de actualizar el menú lateral, agregar la islita de "Productos Vending" 1411 agregarIslita(); 1412 1413 // Agregar las flechas para el submenú de nivel 2 1414 agregarFlechasSubmenuNivel2(); 1415 } 1416 1417 // Función para agregar la islita de "Productos Vending" al final del menú lateral 1418 function agregarIslita() { 1419 const lang = document.documentElement.lang || "es"; 1420 let linkText, linkUrl; 1421 1422 // Determinar el texto y la URL según el idioma 1423 1424 switch (lang) { 1425 case "fr-FR": 1426 linkText = "Des Offres"; 1427 linkUrl = "http://distribucionmayorista.online/fr/promotions"; 1428 break; 1429 case "pt": 1430 linkText = "Ofertas"; 1431 linkUrl = "http://distribucionmayorista.online/pt/promocoes"; 1432 break; 1433 case "en-US": 1434 linkText = "Offers"; 1435 linkUrl = "http://distribucionmayorista.online/en/prices-drop"; 1436 break; 1437 case "de-de": 1438 linkText = "Verkaufsangebote"; 1439 linkUrl = "http://distribucionmayorista.online/de/angebote"; 1440 break; 1441 case "nl-nl": 1442 linkText = "Aanbiedingen"; 1443 linkUrl = "http://distribucionmayorista.online/nl/aanbiedingen"; 1444 break; 1445 case "nl-be": 1446 linkText = "Aanbiedingen"; 1447 linkUrl = "http://distribucionmayorista.online/be/aanbiedingen"; 1448 break; 1449 case "it-it": 1450 linkText = "Offerte"; 1451 linkUrl = "http://distribucionmayorista.online/it/offerte"; 1452 break; 1453 default: 1454 linkText = "Ofertas"; 1455 linkUrl = "http://distribucionmayorista.online/es/ofertas"; 1456 break; 1457 } 1458 1459 const islitaHTML = ` 1460 <div class="row menu_row menu-element menu-element-id-vending"> 1461 <div class="col-12 cbp-menu-column cbp-menu-element menu-element-id-19"> 1462 <div class="cbp-menu-column-inner"> 1463 <div class="row cbp-categories-row"> 1464 <div class="col-12"> 1465 <div class="cbp-category-link-w"> 1466 <a href="${linkUrl}" class="cbp-column-title nav-link cbp-category-title">${linkText}</a> 1467 <a href="${linkUrl}" class="cbp-category-thumb" style="margin-bottom: 0px;"> 1468 <span class="replace-2x img-fluid img-ofert"></span> 1469 </a> 1470 </div> 1471 </div> 1472 </div> 1473 </div> 1474 </div> 1475 </div> 1476 `; 1477 $("#menu-lateral-categorias").append(islitaHTML); 1478 } 1479 1480 // Función para agregar las flechas y controlar el despliegue de los submenús .cbp-hrsub-level2 1481 function agregarFlechasSubmenuNivel2() { 1482 $( 1483 "#menu-lateral-categorias .cbp-hrsub-haslevel2 > .cbp-category-link-w > a", 1484 ).each(function () { 1485 const $link = $(this); 1486 const $submenuLevel2 = $link 1487 .closest(".cbp-hrsub-haslevel2") 1488 .find(".cbp-hrsub-level2") 1489 .hide(); 1490 const subCategoryName = $link.text().trim(); // Texto de la categorÃa 1491 const subCategoryHref = $link.attr("href"); // Enlace de la categorÃa 1492 1493 const translations = { 1494 es: "Todo", 1495 fr: "Tout", 1496 pt: "Tudo", 1497 en: "All", 1498 de: "Alle", 1499 }; 1500 1501 const lang = document.documentElement.lang || "es"; // Por defecto, español 1502 const translatedTodo = translations[lang] || "Todo"; // Traducción 1503 1504 if ($submenuLevel2.length > 0) { 1505 $submenuLevel2.prepend(` 1506 <li> 1507 <div class="cbp-category-link-w"> 1508 <a href="${subCategoryHref}">${translatedTodo} ${subCategoryName}</a> 1509 </div> 1510 </li> 1511 `); 1512 } 1513 1514 if ($submenuLevel2.length > 0) { 1515 const $arrowButtonLevel2 = $( 1516 '<span class="menu-toggle-arrow fas fa-chevron-right"></span>', 1517 ); 1518 $link.prepend($arrowButtonLevel2); 1519 1520 const toggleSubmenuLevel2 = function (e) { 1521 e.preventDefault(); // Prevenir el comportamiento predeterminado 1522 e.stopPropagation(); // Evitar la propagación del evento 1523 1524 const isOpen = $submenuLevel2.is(":visible"); 1525 1526 if (isOpen) {
1527 $submenuLevel2.stop(true, true).slideUp(300); 1528 $arrowButtonLevel2 1529 .removeClass("fa-chevron-down") 1530 .addClass("fa-chevron-right"); 1531 } else { 1532 $submenuLevel2.stop(true, true).slideDown(300); 1533 $arrowButtonLevel2 1534 .removeClass("fa-chevron-right") 1535 .addClass("fa-chevron-down"); 1536 } 1537 }; 1538 1539 $arrowButtonLevel2.on("click", toggleSubmenuLevel2); 1540 $link.on("click", toggleSubmenuLevel2); 1541 } 1542 }); 1543 } 1544 1545 // Ejecutar la primera función, y cuando termine llamará a la segunda 1546 actualizarContenido(); 1547 }); 1548 1549 /* $('#iqitmegamenu-wrapper .row.cbp-categories-row .col-12 > .cbp-category-link-w > a.cbp-category-title').removeAttr('href'); */ 1550 1551 function redondearPrecioTresCifras() { 1552 $(".product-price .elementor-heading-title").each(function () { 1553 // Encuentra el precio en el texto 1554 let priceText = $(this).text().trim(); 1555 1556 // Extraer solo el número del precio (puedes ajustar el selector si es necesario) 1557 let match = priceText.match(/(\d+,\d+)/); 1558 1559 if (match) { 1560 // Extraer el valor del precio 1561 let price = match[1].replace(",", "."); // Reemplaza la coma por punto para manipular el número 1562 1563 // Asegurar que el precio tiene tres cifras decimales 1564 let formattedPrice = parseFloat(price).toFixed(3); 1565 1566 // Volver a colocar el formato y coma original 1567 formattedPrice = formattedPrice.replace(".", ","); 1568 1569 // Reemplazar el texto en el DOM 1570 let updatedText = priceText.replace(match[1], formattedPrice); 1571 $(this).text(updatedText); 1572 } 1573 }); 1574 } 1575 1576 redondearPrecioTresCifras(); 1577 1578 /** 1579 * Productos sin stock 1580 */ 1581 var $info = $("body#product .product-additional-info"); 1582 if ($info.length > 0 && $info.html().trim() !== "") { 1583 // Si .product-additional-info existe y no está vacÃo, eliminamos #purchase-controls 1584 $(".purchase-controls").remove(); 1585 /* console.log("PRODUCTO SIN STOCK"); */ 1586 } 1587 1588 /** 1589 * Eliminar productos duplicados en la lista de deseos 1590 */ 1591 function eliminarProductosDuplicados() { 1592 // Seleccionamos todas las filas de la lista de deseos 1593 var productos = $(".wishlist-products-container .wishlist-products-item"); 1594 /* console.log("PRODUCTOS LISTA", productos); */ 1595 1596 // Creamos un objeto para hacer un seguimiento de los productos que ya hemos encontrado 1597 var productosVistos = {}; 1598 1599 productos.each(function () { 1600 // Seleccionamos el enlace o ID único del producto para identificarlo 1601 var enlaceProducto = $(this).find(".wishlist-product-link").attr("href"); 1602 1603 // Comprobamos si ya hemos visto este producto 1604 if (productosVistos[enlaceProducto]) { 1605 // Si el producto ya está en productosVistos, eliminamos este duplicado 1606 $(this).remove(); 1607 } else { 1608 // Si es un producto nuevo, lo añadimos a productosVistos 1609 productosVistos[enlaceProducto] = true; 1610 } 1611 }); 1612 } 1613 function esperarCargaProductos() { 1614 var interval = setInterval(function () { 1615 // Comprobamos si hay productos en la lista 1616 if ($(".wishlist-products-item").length > 0) { 1617 // Si ya hay productos, ejecutamos la función y dejamos de verificar 1618 eliminarProductosDuplicados(); 1619 clearInterval(interval); // Detenemos el intervalo 1620 } 1621 }, 100); // Verificamos cada 100ms 1622 } 1623 1624 esperarCargaProductos(); // Llamamos la función de espera 1625 1626 /** 1627 * Pop-up Condiciones de venta en ficha producto 1628 */ 1629 $("#terms-sale-popup-link").click(function (e) { 1630 e.preventDefault(); 1631 $("#terms-sale-popup-content").addClass("show"); 1632 }); 1633 1634 $(document).on( 1635 "click", 1636 "#terms-sale-popup-content .elementor-alert-dismiss", 1637 function () { 1638 $("#terms-sale-popup-content").removeClass("show"); 1639 }, 1640 ); 1641 1642 $("#terms-sale-popup-link").click(function (e) { 1643 e.preventDefault(); 1644 $("#terms-sale-popup-content").css("display", ""); 1645 $("#terms-sale-popup-content").addClass("show"); 1646 }); 1647 1648 $(document).on( 1649 "click", 1650 "#terms-sale-popup-content .elementor-alert-dismiss", 1651 function () { 1652 $("#terms-sale-popup-content").removeClass("show").css("display", "none"); 1653 }, 1654 ); 1655 1656 /**
1657 * Borrar etiqueta descuento en caso de estar vacÃas 1658 */ 1659 function removeEmptyDiscountBadges() { 1660 $(".discount-badge .elementor-heading-title").each(function () { 1661 if ($(this).html().trim() === "" || $(this).html().trim() === " ") { 1662 $(this).closest(".discount-badge").remove(); 1663 } 1664 }); 1665 } 1666 removeEmptyDiscountBadges(); 1667 1668 /** 1669 * Limitar los caracteres de los nombres en las minituras y carrito 1670 */ 1671 function truncateText(selector, maxLength) { 1672 $(selector).each(function () { 1673 let text = $(this).text(); 1674 if (text.length > maxLength) { 1675 $(this).text(text.substring(0, maxLength) + "..."); 1676 } 1677 }); 1678 } 1679 1680 truncateText("#blockcart-content .pb-1 a", 20); 1681 truncateText("#cart .product-line-info a", 20); 1682 1683 /** 1684 * Calcula el precio unitario sin descuento para un artÃculo especÃfico. 1685 */ 1686 function calcularPrecioUnitarioEnArticulo(articulo) { 1687 let $articulo = $(articulo); 1688 1689 let precioSinDescuento = parseFloat( 1690 $articulo 1691 .find(".product-og-price span") 1692 .text() 1693 .replace(",", ".") 1694 .replace(/[^\d.]/g, ""), 1695 ); 1696 1697 let ratioUnitario = parseFloat( 1698 $articulo 1699 .find(".product-ratio .elementor-widget-container") 1700 .text() 1701 .replace(",", "."), 1702 ); 1703 1704 if ( 1705 !isNaN(precioSinDescuento) && 1706 !isNaN(ratioUnitario) && 1707 ratioUnitario > 0 1708 ) { 1709 let resultado = (precioSinDescuento / ratioUnitario).toFixed(3) + "â¬"; 1710 1711 $articulo.find(".product-og-ratio p").text(resultado); 1712 } 1713 } 1714 1715 function ejecutarCalculos() { 1716 $(".ce-product-details").each(function () { 1717 calcularPrecioUnitarioEnArticulo(this); 1718 }); 1719 } 1720 1721 function iniciarObserverGlobal() { 1722 const observer = new MutationObserver(function (mutations) { 1723 mutations.forEach(function (mutation) { 1724 mutation.addedNodes.forEach(function (node) { 1725 if (node.nodeType !== 1) return; 1726 1727 if ($(node).hasClass("ce-product-details")) { 1728 calcularPrecioUnitarioEnArticulo(node); 1729 } 1730 1731 $(node) 1732 .find(".ce-product-details") 1733 .each(function () { 1734 calcularPrecioUnitarioEnArticulo(this); 1735 }); 1736 }); 1737 }); 1738 }); 1739 1740 observer.observe(document.body, { 1741 childList: true, 1742 subtree: true, 1743 }); 1744 } 1745 1746 $(window).on("load", function () { 1747 ejecutarCalculos(); 1748 iniciarObserverGlobal(); 1749 }); 1750 1751 // Eliminar tabla de descuentos vacÃa 1752 if ($("body#product .product-discounts-table").children().length === 0) { 1753 $("body#product .product-discounts-table").remove(); 1754 } 1755 1756 /** 1757 * Aplica el cálculo a todos los artÃculos visibles. 1758 */ 1759 function calcularPrecioUnitarioSinDescuento() { 1760 $(".ce-product-grid article").each(function () { 1761 calcularPrecioUnitarioEnArticulo(this); 1762 }); 1763 $("#related-products article").each(function () { 1764 calcularPrecioUnitarioEnArticulo(this); 1765 }); 1766 calcularPrecioUnitarioEnArticulo("#product-detail"); 1767 } 1768 1769 // Inicializamos la función para los elementos ya cargados 1770 calcularPrecioUnitarioSinDescuento(); 1771 1772 /** 1773 * Aplica la función después de hacer clic en el botón `#load-more`. 1774 */ 1775 $("#load-more").on("click", function () { 1776 // Agrega un pequeño retardo para asegurar que los nuevos productos estén en el DOM 1777 setTimeout(() => { 1778 calcularPrecioUnitarioSinDescuento(); 1779 }, 500); // 500ms de retardo ajustable 1780 }); 1781 1782 /** 1783 * Mostrar fecha caducidad producto 1784 */ 1785 function handleCaducidadRow() { 1786 var caducidadRow = $(".product-expiration-date .ce-product-features__row"); 1787 var allowedLabels = ["Cad.", "Exp.", "Val."]; 1788 1789 caducidadRow.each(function () { 1790 var label = $(this).find(".ce-product-features__label").text().trim(); 1791 1792 if (allowedLabels.includes(label)) { 1793 // Mostrar filas Cad., Exp. o Val. 1794 $(this).show(); 1795 $(this).closest("table").show(); 1796 } else { 1797 // Ocultar el resto 1798 $(this).hide(); 1799 } 1800 }); 1801 } 1802 1803 handleCaducidadRow(); 1804 1805 // Configurar el observador principal 1806 const observer = new MutationObserver((mutationsList) => { 1807 observer.disconnect(); // Desactivar temporalmente el observador 1808 try { 1809 mutationsList.forEach((mutation) => { 1810 // Verificar si la mutación tiene nodos añadidos
1811 mutation.addedNodes.forEach((node) => { 1812 if ( 1813 (node.nodeType === Node.ELEMENT_NODE && // Asegurarse de que sea un elemento 1814 node.id === "ce-product-quick-view") || 1815 node.id === "ui-id-1" 1816 ) { 1817 // Ejecutar acciones cuando #ce-product-quick-view es añadido 1818 handleCaducidadRow(); 1819 calcularPrecioUnitarioEnArticulo("#ce-product-quick-view"); 1820 //calcularPrecioUnitarioEnArticulo("#product"); 1821 removeEmptyDiscountBadges(); 1822 showUnitsPerBox(); 1823 // Eliminar tabla de descuentos vacÃa 1824 if ( 1825 $("#ce-product-quick-view .product-discounts-table").children() 1826 .length === 0 1827 ) { 1828 $("#ce-product-quick-view .product-discounts-table").remove(); 1829 } 1830 1831 // Configurar un observador especÃfico para #ce-product-quick-view 1832 /* observeQuickViewContent(node); */ 1833 /* console.log("prueba"); */ 1834 } 1835 }); 1836 }); 1837 } finally { 1838 observer.observe(document.body, { childList: true, subtree: true }); // Reactivar el observador 1839 } 1840 }); 1841 1842 // Configurar el observador en el body para detectar la adición de nodos 1843 observer.observe(document.body, { childList: true, subtree: true }); 1844 1845 // Configurar el observador para detectar cambios en el contenido de #product 1846 const targetProductsNode = document.querySelector("body#product"); 1847 if (targetProductsNode) { 1848 const productsObserver = new MutationObserver((mutationsList) => { 1849 mutationsList.forEach((mutation) => { 1850 if ( 1851 mutation.type === "childList" || 1852 mutation.type === "characterData" 1853 ) { 1854 // Ejecutar las acciones necesarias después de la actualización 1855 handleCaducidadRow(); 1856 /* calcularPrecioUnitarioEnArticulo("#ce-product-quick-view"); */ 1857 removeEmptyDiscountBadges(); 1858 showUnitsPerBox(); 1859 /* console.log("MutationObserver: #product actualizado"); */ 1860 } 1861 }); 1862 }); 1863 1864 // Configurar el observador para observar el contenido y atributos de #product 1865 productsObserver.observe(targetProductsNode, { 1866 childList: true, // Detectar cambios en los hijos 1867 subtree: true, // Detectar cambios en profundidad 1868 characterData: true, // Detectar cambios en el texto de los nodos 1869 attributes: true, // Detectar cambios de atributos (si es necesario) 1870 }); 1871 } 1872 1873 $(".btn-product-quick-preview").on("click", function () { 1874 handleCaducidadRow(); 1875 }); 1876 1877 /** 1878 * Mostrar la badge de oferta en las miniaturas de los productos 1879 * Ocultar `.top-sale-badge .ce-product-badges` si `.ce-product-badge-new` también existe y tiene contenido. 1880 */ 1881 $(".ce-product-grid article").each(function () { 1882 let topSaleBadge = $(this).find(".top-sale-badge .ce-product-badges"); 1883 let newBadge = $(this).find(".ce-product-badge-new"); 1884 1885 // Verifica si ambos elementos existen y si `.ce-product-badge-new` tiene contenido 1886 if ( 1887 topSaleBadge.length > 0 && 1888 newBadge.length > 0 && 1889 newBadge.html().trim() !== "" 1890 ) { 1891 topSaleBadge.hide(); // Oculta `.top-sale-badge .ce-product-badges` 1892 $(this).find(".bottom-sale-badge").show(); // Muestra el elemento correspondiente 1893 } 1894 }); 1895 1896 /** 1897 * Quitar figcaption galerÃas (si está en blanco el figcaption deja un hueco en blanco) 1898 */ 1899 $("#news-section .ce-image-gallery figcaption").each(function () { 1900 let txt = $(this).html().trim(); 1901 if (txt === "") { 1902 $(this).remove(); 1903 } 1904 }); 1905 1906 /** 1907 * Acordeones cerrados por defecto en la home faq section 1908 */ 1909 $("#faq-section .elementor-tab-title").removeClass("elementor-active"); 1910 $("#faq-section .elementor-tab-content").css("display", "none"); 1911 1912 /** 1913 * Capitalizar las marcas en la home 1914 */ 1915 $("#section-featured-brands .facet-label a").each(function () { 1916 let texto = $(this).text().toLowerCase(); 1917 let capitalizado = texto.replace(/\b\w/g, function (letra) { 1918 return letra.toUpperCase(); // Capitalizar la primera letra de cada palabra 1919 }); 1920 $(this).text(capitalizado); // Asignar el texto transformado 1921 }); 1922 1923 /** 1924 * Habilitar Scroll con ratón en #section-featured-products 1925 */ 1926 var isMouseDown = false;
1927 var startX, scrollLeft; 1928 // Detectar cuando se presiona el ratón dentro del contenedor 1929 $(".ce-product-grid").mousedown(function (e) { 1930 isMouseDown = true; 1931 startX = e.pageX - $(this).offset().left; 1932 scrollLeft = $(this).scrollLeft(); 1933 $(this).addClass("is-dragging"); // Cambiar el cursor a "grabbing" 1934 e.preventDefault(); // Prevenir que se seleccione texto o se haga clic en el enlace 1935 }); 1936 1937 // Detectar cuando se suelta el ratón 1938 $(document).mouseup(function () { 1939 isMouseDown = false; 1940 $(".ce-product-grid").removeClass("is-dragging"); // Cambiar el cursor a "grab" 1941 }); 1942 1943 // Detectar el movimiento del ratón para desplazar 1944 $(".ce-product-grid").mousemove(function (e) { 1945 if (!isMouseDown) return; // Solo permite el desplazamiento si el ratón está presionado 1946 e.preventDefault(); // Evita la selección de texto mientras se arrastra 1947 var x = e.pageX - $(this).offset().left; 1948 var walk = (x - startX) * 2; // Ajustar la velocidad de desplazamiento 1949 $(this).scrollLeft(scrollLeft - walk); 1950 }); 1951 1952 // Prevenir el acceso al enlace mientras se arrastra 1953 $(".ce-product-grid a").click(function (e) { 1954 if ($(".ce-product-grid").hasClass("is-dragging")) { 1955 e.preventDefault(); // Evita que el enlace se ejecute si estamos arrastrando 1956 } 1957 }); 1958 1959 // Placeholder en textarea de personalización de productos 1960 function setPlaceholderByLang() { 1961 var placeholders = { 1962 es: "Escriba aquÃ", 1963 fr: "Ãcrivez ici", 1964 pt: "Escreva aqui", 1965 en: "Write here", 1966 de: "Hier schreiben", 1967 }; 1968 1969 var lang = $("html").attr("lang").substring(0, 2).toLowerCase(); 1970 $("#product .elementor-widget-product-customization textarea").attr( 1971 "placeholder", 1972 placeholders[lang] || placeholders["en"], 1973 ); 1974 } 1975 setPlaceholderByLang(); 1976 1977 $(document).ajaxComplete(function () { 1978 calcularPrecioUnitarioSinDescuento(); 1979 calcularPrecioUnitarioEnArticulo("#ce-product-quick-view"); 1980 /* calcularPrecioUnitarioEnArticulo("#product"); */ 1981 truncateText("#cart .product-line-info a", 20); 1982 removeEmptyDiscountBadges(); 1983 showUnitsPerBox(); 1984 if ($("body#product .product-discounts-table").children().length === 0) { 1985 $("body#product .product-discounts-table").remove(); 1986 } 1987 handleCaducidadRow(); 1988 /* console.log("Ajax complete"); */ 1989 }); 1990 1991 // Botón Scroll top 1992 window.onscroll = function () { 1993 const scrollTopBtn = document.getElementById("btnScrollUp"); 1994 if (document.documentElement.scrollTop > 200) { 1995 btnScrollUp.style.display = "block"; // Mostrar el botón 1996 } else { 1997 btnScrollUp.style.display = "none"; // Ocultar el botón 1998 } 1999 }; 2000 2001 /* $.ajax({ 2002 url: 2003 prestashop.urls.base_url + 2004 "index.php?fc=module&module=yourcustommodule&controller=yourcontroller", 2005 type: "POST", 2006 data: { 2007 id_category: prestashop.category.id, 2008 }, 2009 success: function (response) { 2010 $("#imax-seo-adv-desc").html(response); 2011 }, 2012 error: function () { 2013 console.log("Error al cargar el contenido del hook."); 2014 }, 2015 }); */ 2016 2017 // Función para hacer scroll al inicio 2018 function scrollToTop() { 2019 window.scrollTo({ 2020 top: 0, 2021 behavior: "smooth", 2022 }); 2023 } 2024}); 2025 2026document.addEventListener("DOMContentLoaded", function () { 2027 // console.log("Optimización iniciada"); 2028 2029 // 1. Diferir carga de CSS de /assets/cache 2030 /*(function () { 2031 var links = [ 2032 '/assets/cache/theme-24e15d5288.css', 2033 '/assets/cache/theme-278cf95288.css', 2034 '/assets/cache/theme-4478335288.css', 2035 '/assets/cache/theme-5fb5db5288.css', 2036 '/assets/cache/theme-adcc325288.css', 2037 '/assets/cache/theme-dfdb675288.css', 2038 '/assets/cache/theme-e702ec5288.css', 2039 '/assets/cache/theme-fb4dc45288.css' 2040 ]; 2041 links.forEach(function (href) { 2042 var link = document.createElement('link'); 2043 link.rel = 'preload'; 2044 link.as = 'style'; 2045 link.href = href; 2046 link.onload = function () { 2047 this.rel = 'stylesheet'; 2048 console.log('CSS cargado:', href); 2049 }; 2050 document.head.appendChild(link); 2051 }); 2052 })();*/ 2053 2054 // 2. Preconectar y diferir Google Fonts 2055 (function () {
2056 ["https://fonts.googleapis.com", "https://fonts.gstatic.com"].forEach( 2057 function (url) { 2058 var preconnect = document.createElement("link"); 2059 preconnect.rel = "preconnect"; 2060 preconnect.href = url; 2061 if (url.includes("gstatic")) preconnect.crossOrigin = ""; 2062 document.head.appendChild(preconnect); 2063 }, 2064 ); 2065 var fonts = [ 2066 "https://fonts.googleapis.com/css2?family=Roboto&display=swap", 2067 "https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap", 2068 ]; 2069 fonts.forEach(function (href) { 2070 var link = document.createElement("link"); 2071 link.rel = "stylesheet"; 2072 link.href = href; 2073 document.head.appendChild(link); 2074 // console.log('Fuente cargada:', href); 2075 }); 2076 })(); 2077 2078 // Ejecutar al cargar y cuando cambien nodos (AJAX / infinite scroll) 2079 document.addEventListener("DOMContentLoaded", limitProducts); 2080 window.addEventListener("load", limitProducts); 2081 2082 var observerTarget = document.querySelector("#products") || document.body; 2083 if (observerTarget && window.MutationObserver) { 2084 var observer = new MutationObserver(function () { 2085 limitProducts(); 2086 }); 2087 observer.observe(observerTarget, { childList: true, subtree: true }); 2088 } 2089 2090 // También ejecútalo cada 1s un par de veces por si hay scripts que tardan en pintar 2091 var tries = 0; 2092 var interval = setInterval(function () { 2093 limitProducts(); 2094 tries++; 2095 if (tries > 6) clearInterval(interval); 2096 }, 1000); 2097})(); 2098 2099function addFetchPriority() { 2100 // Selecciona todas las imágenes del carousel 2101 const carouselImages = document.querySelectorAll(".elementor-carousel-image"); 2102 2103 carouselImages.forEach((img) => { 2104 if (!img.hasAttribute("fetchpriority")) { 2105 img.setAttribute("fetchpriority", "high"); 2106 2107 // Preload para mejorar LCP 2108 const link = document.createElement("link"); 2109 link.rel = "preload"; 2110 link.as = "image"; 2111 link.href = img.src; 2112 document.head.appendChild(link); 2113 } 2114 }); 2115} 2116 2117// Espera a que Elementor inicialice los widgets 2118document.addEventListener("elementor/frontend/init", function () { 2119 elementorFrontend.hooks.addAction( 2120 "frontend/element_ready/global", 2121 function ($scope) { 2122 addFetchPriority(); 2123 }, 2124 ); 2125}); 2126 2127// Fallback por si alguna imagen ya está cargada 2128window.addEventListener("load", function () { 2129 setTimeout(addFetchPriority, 1000); // Espera 1s para que Elementor termine de renderizar 2130}); 2131 2132document.addEventListener("DOMContentLoaded", function () { 2133 const logo = document.querySelector('img[src*="Logo DMO letras"]'); 2134 2135 if (logo) { 2136 // Reemplaza el src por una versión redimensionada ya optimizada 2137 logo.src = "/dev/cms/Logo_DMO_letras_116x35.png"; 2138 2139 // Ajusta tamaño mostrado 2140 logo.width = 116; 2141 logo.height = 35; 2142 2143 // Añade fetchpriority 2144 logo.setAttribute("fetchpriority", "high"); 2145 2146 // Opcional: agregar srcset para retina 2147 logo.srcset = "/dev/cms/Logo_DMO_letras_232x70.png 2x"; 2148 } 2149}); 2150//Optimizar grid 2151(function () { 2152 // Función para obtener el valor de un parámetro de la URL 2153 function getUrlParam(name, defaultValue) { 2154 const params = new URLSearchParams(window.location.search); 2155 return params.has(name) ? parseInt(params.get(name), 10) : defaultValue; 2156 } 2157 2158 // Función para guardar una cookie 2159 function setCookie(name, value, days = 30) { 2160 const expires = new Date(); 2161 expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); 2162 document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/`; 2163 } 2164 2165 // Valor por defecto de productos por página (ajusta según tu configuración) 2166 const defaultProductsPerPage = 16; 2167 2168 // Obtener el valor 'n' de la URL o usar el valor por defecto 2169 let n = getUrlParam("n", defaultProductsPerPage); 2170 2171 // Ajustar 'n' al múltiplo de 4 más cercano hacia arriba 2172 if (n % 4 !== 0) { 2173 n = Math.ceil(n / 4) * 4; 2174 } 2175 2176 // Guardar en cookie 2177 setCookie("n", n); 2178 2179 // Revisar si la URL ya tiene el parámetro 'n' correcto 2180 const currentUrl = new URL(window.location.href); 2181 if (parseInt(currentUrl.searchParams.get("n")) !== n) { 2182 currentUrl.searchParams.set("n", n); 2183 window.location.href = currentUrl.toString(); // Recargar la página con el valor ajustado 2184 } 2185})(); 2186 2187$(document).ready(function () { 2188 // Guardar los valores originales de la tercera celda 2189 $(".table-product-discounts tbody tr").each(function () { 2190 var celda = $(this).find("td").eq(2); // tercera celda 2191 celda.attr("data-original", celda.text()); // guardamos valor original 2192 }); 2193 2194 // Escuchar cambios en el selector de cantidad de PrestaShop 2195 $(document).on( 2196 "change", 2197 'input[name="qty"], select.qty-selector', 2198 function () { 2199 // Restaurar el valor original de la tercera celda 2200 $(".table-product-discounts tbody tr").each(function () { 2201 var celda = $(this).find("td").eq(2); 2202 celda.text(celda.attr("data-original")); 2203 }); 2204 }, 2205 ); 2206}); 2207 2208/** 2209 * Mostrar únicamente las caracterÃsticas de los productos que contienen "por caja" 2210 */ 2211function showUnitsPerBox(selector) { 2212 var labels = [
2213 "uds. por caja:", 2214 "pour boite", 2215 "por caixa", 2216 "per box", 2217 "pro box", 2218 ]; 2219 2220 $(selector + " .ce-product-features__row").each(function () { 2221 var labelText = $(this) 2222 .find(".ce-product-features__label") 2223 .text() 2224 .toLowerCase(); 2225 2226 var found = labels.some(function (label) { 2227 return labelText.includes(label.toLowerCase()); 2228 }); 2229 2230 if (!found) { 2231 $(this).hide(); 2232 } 2233 }); 2234} 2235 2236// Llamada inicial para ejecutarla en #units-per-box 2237$(document).ready(function () { 2238 showUnitsPerBox("#units-per-box"); 2239}); 2240 2241document.addEventListener("DOMContentLoaded", function () { 2242 var pathParts = window.location.pathname.split("/"); 2243 var categoryName = 2244 pathParts.length > 2 ? pathParts[2].replace(/-/g, " ") : ""; 2245 var categoryId = categoryName.toLowerCase().replace(/\s+/g, "_"); 2246 2247 var products = []; 2248 document.querySelectorAll(".ce-product-name a").forEach(function (el, i) { 2249 var url = el.getAttribute("href"); 2250 var idProduct = url.match(/\/(\d+)-/) ? url.match(/\/(\d+)-/)[1] : ""; 2251 var name = el.innerText.trim(); 2252 2253 products.push({ 2254 item_id: idProduct, 2255 item_name: name, 2256 item_category: categoryName, 2257 index: i + 1, 2258 }); 2259 }); 2260 2261 dataLayer.push({ 2262 event: "view_item_list", 2263 ecommerce: { 2264 item_list_id: categoryId, 2265 item_list_name: categoryName, 2266 items: products, 2267 }, 2268 }); 2269}); 2270 2271document.addEventListener("DOMContentLoaded", function () { 2272 // ID de producto desde la URL (/3712-...) 2273 var idMatch = window.location.pathname.match(/\/(\d+)-/); 2274 var idProduct = idMatch ? idMatch[1] : ""; 2275 2276 // Nombre del producto desde el H1 2277 var productName = document.querySelector("h1.ce-product-name") 2278 ? document.querySelector("h1.ce-product-name").innerText.trim() 2279 : ""; 2280 2281 // CategorÃa desde la URL (/es/chocolates/...) 2282 var pathParts = window.location.pathname.split("/"); 2283 var productCategory = 2284 pathParts.length > 2 ? pathParts[2].replace(/-/g, " ") : ""; 2285 2286 // Precio unitario mostrado 2287 var priceEl = document.querySelector( 2288 '[itemprop="price"], .current-price [content]', 2289 ); 2290 var productPrice = priceEl 2291 ? parseFloat( 2292 priceEl.getAttribute("content") || 2293 priceEl.innerText.replace(/[^\d.,]/g, "").replace(",", "."), 2294 ) 2295 : 0; 2296 2297 // Push al dataLayer 2298 dataLayer.push({ 2299 event: "view_item", 2300 ecommerce: { 2301 currency: "EUR", 2302 value: productPrice, 2303 items: [ 2304 { 2305 item_id: idProduct, 2306 item_name: productName, 2307 item_category: productCategory, 2308 price: productPrice, 2309 quantity: 1, 2310 }, 2311 ], 2312 }, 2313 }); 2314 2315 console.log("view_item enviado:", { 2316 idProduct, 2317 productName, 2318 productCategory, 2319 productPrice, 2320 }); 2321}); 2322document.addEventListener("DOMContentLoaded", () => { 2323 const addToCartBtns = document.querySelectorAll( 2324 "a[href*='#ce-action=addToCart']", 2325 ); 2326 console.log("ð Botones encontrados:", addToCartBtns.length); 2327 2328 addToCartBtns.forEach((btn, index) => { 2329 btn.addEventListener("click", (e) => { 2330 console.log(`\nð¢ Clic en botón add_to_cart #${index + 1}`, btn); 2331 2332 // Miramos el contenedor más cercano (ajústalo según tu HTML real) 2333 const productContainer = 2334 btn.closest(".elementor-widget, .product, .elementor-column, li") || 2335 document; 2336 console.log("ð¦ Contenedor detectado:", productContainer); 2337 2338 // Nombre del producto 2339 const nameEl = productContainer.querySelector( 2340 ".product-title, .elementor-heading-title, h2, h3, .label", 2341 ); 2342 console.log("ð¤ nameEl encontrado:", nameEl); 2343 const name = nameEl ? nameEl.innerText.trim() : "Producto sin nombre"; 2344 2345 // Precio del producto 2346 const priceEl = productContainer.querySelector( 2347 ".price, .product-price, .woocommerce-Price-amount, .value", 2348 ); 2349 console.log("ð¶ priceEl encontrado:", priceEl); 2350 const priceText = priceEl ? priceEl.innerText.trim() : "0"; 2351 const price = 2352 parseFloat( 2353 priceText 2354 .replace(/\./g, "") 2355 .replace(",", ".") 2356 .replace(/[^\d.]/g, ""), 2357 ) || 0; 2358 2359 // ID del producto 2360 const id =
2361 productContainer.dataset.idProduct || 2362 name.replace(/\s+/g, "-").toLowerCase(); 2363 2364 // URL del producto 2365 const linkEl = productContainer.querySelector("a[href]"); 2366 const url = linkEl ? linkEl.href : window.location.href; 2367 2368 // CategorÃa (sacada de la URL si existe /es/categoria/) 2369 const category = url.includes("/es/") 2370 ? url.split("/es/")[1].split("/")[0] 2371 : "general"; 2372 2373 const product = { 2374 item_id: id, 2375 item_name: name, 2376 price: price, 2377 quantity: 1, 2378 item_category: category, 2379 item_url: url, 2380 }; 2381 2382 // Enviar al dataLayer 2383 window.dataLayer = window.dataLayer || []; 2384 window.dataLayer.push({ 2385 event: "add_to_cart", 2386 ecommerce: { 2387 currency: "EUR", 2388 value: product.price, 2389 items: [product], 2390 }, 2391 }); 2392 2393 console.log("â Evento add_to_cart enviado:", product); 2394 }); 2395 }); 2396}); 2397 2398// Alternativa: disparar automáticamente al cargar la página de checkout 2399document.addEventListener("DOMContentLoaded", triggerBeginCheckout); 2400 2401// Wait for the DOM to load 2402document.addEventListener("DOMContentLoaded", function () { 2403 // Get all shipping radio buttons 2404 const shippingOptions = document.querySelectorAll( 2405 'input[name^="delivery_option"]', 2406 ); 2407 2408 shippingOptions.forEach((option) => { 2409 option.addEventListener("change", function () { 2410 const selectedOption = this; 2411 const label = document.querySelector(`label[for="${selectedOption.id}"]`); 2412 2413 if (label) { 2414 const carrierName = 2415 label.querySelector(".carrier-name")?.innerText || ""; 2416 const carrierDelay = 2417 label.querySelector(".carrier-delay")?.innerText || ""; 2418 const carrierPrice = 2419 label.querySelector(".carrier-price")?.innerText || ""; 2420 2421 // Push to dataLayer 2422 window.dataLayer = window.dataLayer || []; 2423 window.dataLayer.push({ 2424 event: "add_shipping_info", 2425 shipping_method: carrierName, 2426 shipping_price: carrierPrice, 2427 shipping_delay: carrierDelay, 2428 }); 2429 2430 console.log("DataLayer push:", { 2431 shipping_method: carrierName, 2432 shipping_price: carrierPrice, 2433 shipping_delay: carrierDelay, 2434 }); 2435 } 2436 }); 2437 }); 2438}); 2439 2440document.addEventListener("DOMContentLoaded", function () { 2441 var form = document.querySelector("#js-delivery"); 2442 var continueBtn = form ? form.querySelector('button[type="submit"]') : null; 2443 2444 if (continueBtn && form) { 2445 continueBtn.addEventListener("click", function (e) { 2446 e.preventDefault(); 2447 2448 // ---- Subtotal ---- 2449 var subtotalEl = document.querySelector("#cart-subtotal-products .value"); 2450 var cartSubtotal = 0; 2451 if (subtotalEl) { 2452 var subtotalText = subtotalEl.textContent 2453 .trim() 2454 .replace(/\./g, "") 2455 .replace(",", "."); 2456 cartSubtotal = parseFloat(subtotalText) || 0; 2457 } 2458 2459 // ---- Cupón ---- 2460 var couponEl = document.querySelector( 2461 '#promo-code input[name="discount_name"]', 2462 ); 2463 var cartCoupon = couponEl ? couponEl.value.trim() : ""; 2464 2465 // ---- Productos ---- 2466 var cartLines = Array.from( 2467 document.querySelectorAll(".cart-summary-product"), 2468 ); 2469 var items = cartLines.map(function (el) { 2470 var nameEl = el.querySelector(".product-line-info .label"); 2471 var priceEl = el.querySelector(".unit-price .value"); 2472 var qtyEl = el.querySelector(".js-cart-line-product-quantity"); 2473 var linkEl = el.querySelector(".product-line-info a"); 2474 2475 var price = priceEl 2476 ? parseFloat( 2477 priceEl.textContent.trim().replace(/\./g, "").replace(",", "."), 2478 ) || 0 2479 : 0; 2480 var quantity = qtyEl ? parseInt(qtyEl.value) || 1 : 1; 2481 var url = linkEl ? linkEl.href : ""; 2482 2483 return { 2484 item_id: el.dataset.id || "", 2485 item_name: nameEl ? nameEl.textContent.trim() : "", 2486 item_category: el.dataset.category || "", 2487 price: price, 2488 quantity: quantity, 2489 item_url: url, 2490 }; 2491 }); 2492 2493 // ---- EnvÃo del evento con gtag ---- 2494 if (typeof gtag === "function") { 2495 gtag("event", "begin_checkout", { 2496 currency: "EUR", 2497 value: cartSubtotal, 2498 coupon: cartCoupon, 2499 items: items, 2500 }); 2501 } else { 2502 console.error("gtag no está definido"); 2503 } 2504 2505 console.log("Evento begin_checkout enviado:", { 2506 currency: "EUR", 2507 value: cartSubtotal, 2508 coupon: cartCoupon, 2509 items: items, 2510 }); 2511 2512 // ---- Asegurar que se mande antes de redirigir ---- 2513 setTimeout(function () { 2514 form.submit(); 2515 }, 500); 2516 }); 2517 } 2518}); 2519 2520(function () { 2521 function getCartItems() { 2522 let items = []; 2523 2524 document 2525 .querySelectorAll("#cart-summary-product-list .cart-summary-product") 2526 .forEach((el) => { 2527 const name = 2528 el.querySelector(".product-line-info .label")?.innerText.trim() || ""; 2529 const id = 2530 el.querySelector("input.js-cart-line-product-quantity")?.dataset 2531 .productId || ""; 2532 const quantity = parseInt( 2533 el.querySelector("input.js-cart-line-product-quantity")?.value || "0", 2534 10, 2535 ); 2536 const priceText = el 2537 .querySelector(".unit-price .value") 2538 ?.innerText.replace("â¬", "") 2539 .replace(",", ".") 2540 .trim(); 2541 const price = parseFloat(priceText) || 0; 2542 const link = 2543 el.querySelector(".product-line-info .label")?.getAttribute("href") || 2544 ""; 2545 const image = el.querySelector(".product-image img")?.src || ""; 2546 2547 items.push({ 2548 item_id: id, 2549 item_name: name, 2550 quantity: quantity, 2551 price: price, 2552 item_url: link, 2553 item_image: image, 2554 }); 2555 }); 2556 2557 return items; 2558 } 2559 2560 // Lanzamos el evento begin_checkout con lo que hay en el carrito 2561 const items = getCartItems(); 2562 2563 window.dataLayer = window.dataLayer || []; 2564 window.dataLayer.push({ 2565 event: "begin_checkout", 2566 ecommerce: { 2567 currency: "EUR", 2568 items: items, 2569 }, 2570 }); 2571 2572 console.log("begin_checkout event enviado:", items); 2573})(); 2574 2575(function () { 2576 // Reutilizamos la función getCartItems() para extraer productos del mini carrito 2577 function getCartItems() { 2578 let items = []; 2579 document
2580 .querySelectorAll("#blockcart-content .cart-products li") 2581 .forEach((el) => { 2582 const inputQty = el.querySelector( 2583 "input.js-cart-line-product-quantity", 2584 ); 2585 const linkEl = el.querySelector(".col-info a"); 2586 const priceEl = el.querySelector(".col-info .col span:last-child"); 2587 const imgEl = el.querySelector(".product-image img"); 2588 2589 if (!inputQty || !linkEl || !priceEl) return; 2590 2591 const id = inputQty.dataset.productId; 2592 const name = linkEl.innerText.trim(); 2593 const quantity = parseInt(inputQty.value || "0", 10); 2594 const priceText = priceEl.innerText 2595 .replace("â¬", "") 2596 .replace(/\./g, "") 2597 .replace(",", ".") 2598 .trim(); 2599 const price = parseFloat(priceText) || 0; 2600 const link = linkEl.href; 2601 const image = imgEl ? imgEl.src : ""; 2602 2603 items.push({ 2604 item_id: id, 2605 item_name: name, 2606 quantity: quantity, 2607 price: price, 2608 item_url: link, 2609 item_image: image, 2610 }); 2611 }); 2612 return items; 2613 } 2614 2615 function getSelectedPaymentMethod() { 2616 const selected = document.querySelector( 2617 'input[name="payment-option"]:checked', 2618 ); 2619 return selected ? selected.dataset.moduleName || selected.id : ""; 2620 } 2621 2622 function getCartTotal() { 2623 const totalEl = document.querySelector( 2624 "#blockcart-content .cart-totals .flex-cart-totals-total .value", 2625 ); 2626 if (!totalEl) return 0; 2627 const totalText = totalEl.innerText 2628 .replace("â¬", "") 2629 .replace(/\./g, "") 2630 .replace(",", ".") 2631 .trim(); 2632 return parseFloat(totalText) || 0; 2633 } 2634 2635 function pushAddPaymentInfo() { 2636 const items = getCartItems(); 2637 const paymentMethod = getSelectedPaymentMethod(); 2638 const cartTotal = getCartTotal(); 2639 2640 if (items.length > 0 && paymentMethod) { 2641 window.dataLayer = window.dataLayer || []; 2642 window.dataLayer.push({ 2643 event: "add_payment_info", 2644 ecommerce: { 2645 currency: "EUR", 2646 value: cartTotal, 2647 payment_type: paymentMethod, 2648 items: items, 2649 }, 2650 }); 2651 console.log("add_payment_info enviado:", { 2652 paymentMethod, 2653 cartTotal, 2654 items, 2655 }); 2656 } 2657 } 2658 2659 // Ejecutar cuando se seleccione un método de pago 2660 document.querySelectorAll('input[name="payment-option"]').forEach((input) => { 2661 input.addEventListener("change", pushAddPaymentInfo); 2662 }); 2663 2664 // También ejecutar al cargar la página si ya hay un método seleccionado 2665 document.addEventListener("DOMContentLoaded", pushAddPaymentInfo); 2666})();
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.