1(function ($) { 2 $(document).ready(function () { 3 const _ajax_url = cjpg_ajax_obj.ajaxurl; 4 const _nonce = cjpg_ajax_obj.nonce; 5 const _is_rtl = cjpg_ajax_obj.is_rtl; 6 const _words = cjpg_ajax_obj.words; 7 let wakeLock = null; 8 let ytPlayer; 9 10 $(document).on( 11 "click", 12 ".search_header_area_desktop_btn .button_search_toggle", 13 function (e) { 14 e.preventDefault(); 15 _header.show_search_desktop($(this)); 16 }, 17 ); 18 $(document).on( 19 "click", 20 ".search_header_area_mobile_btn .button_search_toggle", 21 function (e) { 22 e.preventDefault(); 23 _header.toggle_search_mobile($(this)); 24 }, 25 ); 26 $(document).on("click", function (e) { 27 _header.hide_search_desktop(e); 28 }); 29 30 $(document).on("click", ".header_mobile_icon_btn", function (e) { 31 e.preventDefault(); 32 _header.toggle_mobile_menu($(this)); 33 }); 34 $(document).on( 35 "click", 36 ".mobile_header_inner_block_inner .menu-item-has-children > a", 37 function (e) { 38 _header.toggle_mobile_menu_inside( 39 e, 40 $(this), 41 $(".mobile_header_inner_block_inner .menu-item-has-children"), 42 ); 43 }, 44 ); 45 $(document).on("click", ".mobile_overlay_close", function (e) { 46 e.preventDefault(); 47 const $btn = $(".header_mobile_icon_btn.active").first(); 48 if ($btn.length) { 49 _header.toggle_mobile_menu($btn, true); 50 } 51 }); 52 $(document).on("click", "#mobile_header_inner_block_toggle", function (e) { 53 if ($(e.target).is("#mobile_header_inner_block_toggle")) { 54 const $btn = $(".header_mobile_icon_btn.active").first(); 55 if ($btn.length) { 56 _header.toggle_mobile_menu($btn, true); 57 } 58 } 59 }); 60 $(window).on("scroll", function () { 61 if ($(this).scrollTop() > 100) { 62 _header.sticky(true); 63 } else { 64 _header.sticky(false); 65 } 66 }); 67 68 const _header = { 69 sticky: function (bool) { 70 const _t_header = $(".maimon_header"); 71 if (window.innerWidth <= 1024) { 72 _t_header.removeClass("stickyHeader"); 73 return; 74 } 75 if (bool) { 76 _t_header.addClass("stickyHeader"); 77 } else { 78 _t_header.removeClass("stickyHeader"); 79 } 80 }, 81 show_search_desktop: function ($this) { 82 const _target = $($this.attr("data-target")); 83 const _parent = $("#" + $this.attr("data-parent")); 84 if (_target && _target.length > 0 && _parent && _parent.length > 0) { 85 _parent.hide(); 86 _target.removeClass("invisible"); 87 } 88 return true; 89 }, 90 hide_search_desktop: function (event) { 91 const $el = $(".search_area_widget"); 92 const $btn = $(".button_search_toggle"); 93 const $btn_parent = $("#" + $btn.attr("data-parent")); 94 if ( 95 !$el.is(event.target) && 96 !$el.has(event.target).length && 97 !$btn.is(event.target) && 98 !$btn.has(event.target).length && 99 !$el.hasClass("invisible") 100 ) { 101 $el.addClass("invisible"); // Hide the block 102 $btn_parent.show(); 103 } 104 }, 105 toggle_search_mobile: function ($this, bool = false) { 106 const _target = $("#" + $this.attr("aria-controls")); 107 const _o1 = $(".search_open_svg"); 108 const _o2 = $(".search_close_svg"); 109 if (_target && _target.length > 0) { 110 if (!$this.hasClass("active") && bool === false) { 111 _target.slideDown(200); 112 _o1.hide(); 113 _o2.show(); 114 $this.addClass("active"); 115 } else { 116 _target.slideUp(200); 117 _o1.show(); 118 _o2.hide(); 119 $this.removeClass("active"); 120 } 121 } 122 const mobile_menu_btn = $(".header_mobile_icon_btn"); 123 if ( 124 mobile_menu_btn && 125 mobile_menu_btn.length > 0 && 126 mobile_menu_btn.hasClass("active") && 127 $this.hasClass("active") 128 ) { 129 mobile_menu_btn.removeClass("active"); 130 this.toggle_mobile_menu(mobile_menu_btn, true); 131 } 132 return true; 133 }, 134 toggle_mobile_menu: function ($this, bool = false) { 135 const _target = $("#" + $this.attr("aria-controls")); 136 const _body = $("body"); 137 const _html = $("html"); 138 if (_target && _target.length > 0) { 139 if (!$this.hasClass("active") && bool === false) { 140 const topBarHeight = Math.round( 141 $(".maimon-top-bar:visible").outerHeight() || 0, 142 ); 143 const headerHeight = Math.round( 144 $(".maimon_header").outerHeight() || 0, 145 ); 146 const overlayTop = Math.max(topBarHeight + headerHeight - 1, 0); 147 const overlayHeight = Math.max(window.innerHeight - overlayTop, 0); 148 _html.addClass("preventor"); 149 _body.addClass("preventor"); 150 _target.find(".menu-item-has-children").removeClass("active"); 151 _target 152 .css({ top: overlayTop + "px", height: 0, display: "block" }) 153 .animate({ height: overlayHeight + "px" }, 200); 154 $this.addClass("active"); 155 } else { 156 _html.removeClass("preventor"); 157 _body.removeClass("preventor"); 158 _target.animate({ height: 0 }, 200, function () { 159 $(this).css("display", "none"); 160 }); 161 $this.removeClass("active"); 162 } 163 const _mobile_search_btn = $( 164 ".search_header_area_mobile_btn .button_search_toggle", 165 ); 166 if ( 167 _mobile_search_btn && 168 _mobile_search_btn.length > 0 && 169 _mobile_search_btn.hasClass("active") && 170 $this.hasClass("active") 171 ) { 172 _mobile_search_btn.removeClass("active"); 173 this.toggle_search_mobile(_mobile_search_btn, true); 174 } 175 } 176 return true; 177 }, 178 toggle_mobile_menu_inside: function (e, $this, $all) { 179 const $item = $this.closest(".menu-item-has-children"); 180 if (!$item.length || !$item.children(".sub-menu").length) { 181 return true; 182 } 183 e.preventDefault(); 184 if ($item.hasClass("active")) { 185 $item.removeClass("active"); 186 } else { 187 $all.removeClass("active"); 188 $item.addClass("active"); 189 } 190 return true; 191 }, 192 handle_hover_image: function () { 193 $(".menu-link").each(function () { 194 const $link = $(this); 195 const $defaultImg = $link.find(".menu-icon-default"); 196 const $hoverImg = $link.find(".menu-icon-hover"); 197 if ($defaultImg.length && $hoverImg.length && $hoverImg.attr("src")) { 198 const defaultSrc = $defaultImg.attr("src"); 199 const hoverSrc = $hoverImg.attr("src"); 200 $hoverImg.remove(); 201 // Keep brand logos in original colors. 202 // Only force hover asset when the known default logo is white-on-transparent. 203 const isWhiteMaimonsSvg = /\/Maimons\.svg(?:\?|$)/i.test( 204 defaultSrc, 205 ); 206 if (isWhiteMaimonsSvg) { 207 $defaultImg.attr("src", hoverSrc); 208 return; 209 } 210 $link.on("mouseenter focus", function () { 211 $defaultImg.attr("src", hoverSrc); 212 }); 213 $link.on("mouseleave blur", function () { 214 $defaultImg.attr("src", defaultSrc); 215 }); 216 } else if ($hoverImg.length) { 217 $hoverImg.remove(); 218 } 219 }); 220 }, 221 }; 222 _header.handle_hover_image(); 223 224 const FAVORITES_KEY = "mamon_favorites_list"; 225 const _favorites = { 226 init: function () { 227 this.markFavoritesOnLoad(); 228 this.bindEvents(); 229 this.loadFavoritesPageIfExists(); 230 }, 231 bindEvents: function () { 232 $(document).on("click", ".toggle_favorite", function (e) { 233 e.preventDefault(); 234 _favorites.toggle_favorite($(this)); 235 }); 236 }, 237 toggle_favorite: function ($this) { 238 const _post_id = $this.attr("data-id"); 239 const _target = $("#favorite_btn_wrapper_inner_toggle_" + _post_id); 240 if (!_post_id) return true; 241 let favorites = this.getFavorites(); 242 const index = favorites.indexOf(_post_id); 243 const isNowFavorite = index === -1; 244 if (isNowFavorite) { 245 favorites.push(_post_id); 246 _target.addClass("favorite_item"); 247 this.setFilledIcon(_target); 248 } else { 249 favorites.splice(index, 1); 250 _target.removeClass("favorite_item"); 251 this.setOutlineIcon(_target); 252 } 253 this.saveFavorites(favorites); 254 return true; 255 }, 256 setFilledIcon: function ($el) { 257 $el.html(` 258 <svg xmlns="http://www.w3.org/2000/svg" width="42" height="36" viewBox="0 0 42 36" fill="none"> 259 <path d="M12 1C5.925 1 1 5.87823 1 11.8955C1 22.7911 14 32.6961 21 35C28 32.6961 41 22.7911 41 11.8955C41 5.87823 36.075 1 3
2590 1C26.28 1 22.99 2.82946 21 5.62961C19.9857 4.19854 18.6382 3.03062 17.0715 2.22475C15.5049 1.41887 13.7653 0.998766 12 1Z" fill="#334783" stroke="#334783" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 260 </svg> 261 `); 262 }, 263 setOutlineIcon: function ($el) { 264 $el.html(` 265 <svg xmlns="http://www.w3.org/2000/svg" width="42" height="36" viewBox="0 0 42 36" fill="none"> 266 <path d="M12 1C5.925 1 1 5.87823 1 11.8955C1 22.7911 14 32.6961 21 35C28 32.6961 41 22.7911 41 11.8955C41 5.87823 36.075 1 30 1C26.28 1 22.99 2.82946 21 5.62961C19.9857 4.19854 18.6382 3.03062 17.0715 2.22475C15.5049 1.41887 13.7653 0.998766 12 1Z" stroke="#334783" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 267 </svg> 268 `); 269 }, 270 getFavorites: function () { 271 try { 272 return JSON.parse(localStorage.getItem(FAVORITES_KEY)) || []; 273 } catch (e) { 274 return []; 275 } 276 }, 277 saveFavorites: function (list) { 278 localStorage.setItem(FAVORITES_KEY, JSON.stringify(list)); 279 }, 280 markFavoritesOnLoad: function () { 281 const favorites = this.getFavorites(); 282 favorites.forEach(function (_post_id) { 283 const $target = $("#favorite_btn_wrapper_inner_toggle_" + _post_id); 284 $target.addClass("favorite_item"); 285 _favorites.setFilledIcon($target); 286 }); 287 }, 288 loadFavoritesPageIfExists: function () { 289 const _fv = this; 290 const $favoritesPage = $("#page_favorite_list_wrapper"); 291 if ($favoritesPage && $favoritesPage.length > 0) { 292 const favorites = this.getFavorites(); 293 if (favorites.length === 0) { 294 $favoritesPage.html( 295 '<div class="favorite_list_wrapper_empty"><h5>' + 296 cjpg_ajax_obj.words.you_dont_have_favorites_recipes_yet + 297 "</h5></div>", 298 ); 299 return; 300 } 301 _fv.favorite_loader(true); 302 $.ajax({ 303 url: _ajax_url, 304 type: "POST", 305 dataType: "json", 306 data: { 307 action: "get_favorites_html", 308 ids: favorites, 309 nonce: _nonce, 310 }, 311 success: function (response) { 312 _fv.favorite_loader(); 313 if (response.success) { 314 $favoritesPage.html(response.data.html); 315 } else { 316 $favoritesPage.html(response.data.html); 317 } 318 }, 319 error: function () { 320 _fv.favorite_loader(); 321 $favoritesPage.html( 322 '<div class="favorite_list_wrapper_empty"><h5>' + 323 cjpg_ajax_obj.words.you_dont_have_favorites_recipes_yet + 324 "</h5></div>", 325 ); 326 }, 327 }); 328 } 329 }, 330 favorite_loader: function (bool = false) { 331 const _loader = $("#favorite_loader"); 332 if (_loader && _loader.length > 0) { 333 if (bool) { 334 _loader.show(); 335 } else { 336 _loader.hide(); 337 } 338 } 339 }, 340 }; 341 _favorites.init(); 342 343 const _favorites_old = { 344 init: function () {}, 345 toggle_favorite: function ($this) { 346 const _action = "maimon_favorite_toggle"; 347 const _post_id = $this.attr("data-id"); 348 const _target = $("#favorite_btn_wrapper_inner_toggle_" + _post_id); 349 if (_post_id) { 350 const _d = { 351 action: _action, 352 nonce: _nonce, 353 post_id: _post_id, 354 }; 355 this.send_ajax(_d, "POST", "toggle_favorite", { _target: _target }); 356 } 357 return true; 358 }, 359 send_ajax: function (_d, method, callback = "", $args = {}) { 360 let _s_ajax = $.ajax({ 361 url: _ajax_url, 362 data: _d, 363 dataType: "json", 364 type: method, 365 xhrFields: { 366 withCredentials: true, // needed only for cross-site or subdomains 367 }, 368 }); 369 _s_ajax.done(function (response) { 370 if (callback === "toggle_favorite") { 371 if (response.data === "2") { 372 $args._target.addClass("favorite_item"); 373 } else { 374 $args._target.removeClass("favorite_item"); 375 } 376 } else { 377 console.log(response); 378 } 379 }); 380 _s_ajax.fail(function (jqXHR, textStatus, errorThrown) { 381 console.error("AJAX Error:", textStatus, errorThrown); 382 }); 383 }, 384 }; 385 386 $(document).on( 387 "change", 388 ".maimon_career_form_inner_field #resume_id_file", 389 function (e) { 390 _forms.file_upload($(this)); 391 }, 392 ); 393 const _forms = { 394 init: function () { 395 this.normalize_contact_message_placeholder(); 396 }, 397 normalize_contact_message_placeholder: function () { 398 const defaultValues = ["×× ×× × ×קש××××...", "×× ×× × ×קש××××â¦"]; 399 $( 400 '.contact-form textarea, .wpcf7 textarea, textarea#message, textarea[name="message"]', 401 ).each(function () { 402 const $field = $(this); 403 const currentValue = ($field.val() || "").trim(); 404 const initialValue = (this.defaultValue || "").trim(); 405 const currentPlaceholder = ($field.attr("placeholder") || "").trim(); 406 const fallbackText = defaultValues.includes(currentValue) 407 ? currentValue 408 : initialValue; 409 410 if (!currentPlaceholder && fallbackText) { 411 $field.attr("placeholder", fallbackText); 412 } 413 414 if ( 415 defaultValues.includes(currentValue) || 416 defaultValues.includes(initialValue) 417 ) { 418 $field.val(""); 419 this.defaultValue = ""; 420 } 421 }); 422 }, 423 file_upload: function ($this) { 424 const _target = $(".career_resume_text_file"); 425 const fileName = $this.val().split("\\").pop(); 426 if (!$this.hasClass("chk")) { 427 let _txt = $this.text(); 428 $this.attr("data-opp", _txt); 429 } 430 _target.html(""); 431 if (fileName) { 432 _target.text(fileName); 433 } else { 434 _target.text($this.attr("data-opp")); 435 } 436 $this.addClass("chk"); 437 return true; 438 }, 439 }; 440 _forms.init(); 441 442 $(document).on("click", ".btn_action_increase", function (e) { 443 e.preventDefault(); 444 _accessibility.increase_font($(this)); 445 }); 446 $(document).on("click", ".btn_action_decrease", function (e) { 447 e.preventDefault(); 448 _accessibility.decrease_font($(this)); 449 }); 450 $(document).on("click", ".btn_action_print", function (e) { 451 e.preventDefault(); 452 _accessibility.print_recipe($(this)); 453 }); 454 $(document).on("click", ".button_screen_locker", function (e) { 455 e.preventDefault(); 456 _accessibility.lock_mobile_screen($(this)); 457 }); 458 const _accessibility = { 459 increase_font: function ($this) { 460 const _op = $(".btn_action_decrease"); 461 const _op_max = _op.attr("data-max"); 462 const _max = 6; 463 const _max_data = $this.attr("data-max"); 464 let _calc = Number(_max_data) + 1; 465 if (_calc > _max) { 466 return true; 467 } 468 $this.attr("data-max", _calc); 469 _op.attr("data-max", Number(_op_max) + 1); 470 this.change_font_size_screen("2"); 471 return true; 472 }, 473 decrease_font: function ($this) { 474 const _op = $(".btn_action_increase"); 475 const _op_max = _op.attr("data-max"); 476 const _max = 1; 477 const _max_data = $this.attr("data-max"); 478 let _calc = Number(_max_data) - 1; 479 if (_calc < _max) { 480 return true; 481 } 482 $this.attr("data-max", _calc); 483 _op.attr("data-max", Number(_op_max) - 1); 484 this.change_font_size_screen("1"); 485 return true; 486 }, 487 change_font_size_screen: function (side) { 488 $("span,h1,h2,h3,h4,h5,h6,p,a,strong,b,li,label,input,button") 489 .not(".line_buttons_recipes_wrapper *") 490 .each(function () { 491 const currentSize = parseInt($(this).css("font-size")); 492 if (side === "1") { 493 // decrease size 494 $(this).css("font-size", currentSize - 5 + "px"); 495 } else { 496 $(this).css("font-size", currentSize + 5 + "px"); 497 } 498 }); 499 }, 500 print_recipe: function ($this) { 501 const _p_id = $this.attr("data-id"); 502 if (!_p_id) { 503 return false;
504 } 505 const _d = { 506 post_id: _p_id, 507 action: "maimon_print_recipe", 508 }; 509 this.send_ajax("POST", _d, "print_recipe"); 510 return true; 511 }, 512 lock_mobile_screen: function ($this) { 513 if (wakeLock !== null) { 514 this.lock_mobile_screen_disable(); 515 $this.removeClass("active"); 516 } else { 517 this.lock_mobile_screen_enable(); 518 $this.addClass("active"); 519 } 520 return true; 521 }, 522 lock_mobile_screen_disable: function () { 523 if (_general.isSafari()) { 524 if (document.getElementById("iosWakeLock")) return; 525 let video = document.createElement("video"); 526 video.id = "iosWakeLock"; 527 video.playsInline = true; 528 video.loop = true; 529 video.muted = true; // Ensure it plays silently 530 video.style.display = "none"; 531 video.src = "data:video/mp4;base64,AAAA..."; // Replace with actual Base64 data 532 document.body.appendChild(video); 533 video 534 .play() 535 .catch((error) => 536 console.error("Wake lock video failed to play:", error), 537 ); 538 } else { 539 wakeLock.release().then(() => { 540 wakeLock = null; 541 }); 542 } 543 }, 544 lock_mobile_screen_enable: async function () { 545 if (_general.isSafari()) { 546 let video = document.getElementById("iosWakeLock"); 547 if (video) { 548 video.src = "data:video/mp4;base64,AAAA..."; // Base64 silent video 549 video.play(); 550 video.remove(); // Remove from DOM 551 } 552 } else { 553 if ("wakeLock" in navigator) { 554 try { 555 wakeLock = await navigator.wakeLock.request("screen"); 556 wakeLock.addEventListener("release", () => { 557 console.log("Screen Wake Lock was released."); 558 }); 559 } catch (err) { 560 console.error(`Wake Lock failed: ${err.name}, ${err.message}`); 561 } 562 } else { 563 console.warn("Wake Lock API is not supported in this browser."); 564 } 565 } 566 }, 567 send_ajax: function (method, data, callback) { 568 const _fv = this; 569 _general.show_loader(true); 570 let ajax_data, _s_ajax; 571 ajax_data = data; 572 ajax_data["nonce"] = _nonce; 573 _s_ajax = $.ajax({ 574 url: _ajax_url, 575 data: ajax_data, 576 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 577 contentType: "application/json; charset=utf-8", 578 dataType: "json", 579 type: method, 580 }); 581 _s_ajax.done(function (response, msg) { 582 _general.show_loader(false); 583 if (response) { 584 if (callback === "print_recipe") { 585 _fv.handle_response(response.data); 586 } 587 return true; 588 } 589 }); 590 _s_ajax.fail(function (error, textStatus) { 591 _general.show_loader(false); 592 console.log(error); 593 }); 594 }, 595 handle_response: function (response) { 596 const _template = response.data; 597 const tempDiv = $("<div>").html(_template); // Create a temporary div with AJAX content 598 this.printContent(tempDiv); 599 }, 600 printContent: function (content) { 601 const printWindow = window.open("", "_blank"); 602 let stylesheets = document.querySelectorAll( 603 'link[rel="stylesheet"], style', 604 ); 605 printWindow.document.write("<html><head><title>Print</title>"); 606 stylesheets.forEach((style) => { 607 let clone = style.cloneNode(true); 608 printWindow.document.head.appendChild(clone); 609 }); 610 printWindow.document.write("</head><body>"); 611 printWindow.document.write(content.html()); // Insert the dynamic content 612 printWindow.document.write("</body></html>"); 613 printWindow.document.close(); 614 printWindow.focus(); 615 printWindow.print(); 616 printWindow.close(); 617 }, 618 }; 619 620 $(document).on("change", ".in_post_maimon_checkbox_line_chk", function (e) { 621 e.preventDefault(); 622 _general.toggle_line_label_chk($(this)); 623 }); 624 $(document).on("click", ".video-link", function (e) { 625 e.preventDefault(); 626 _general.video_link($(this)); 627 }); //Handle video modal 628 $(document).on("click", "#videoModal, .close", function (e) { 629 _general.video_link_close(e); 630 }); // Close modal on click outside or on close button 631 const _general = { 632 init: function () { 633 this.init_alice(); 634 }, 635 init_alice: function () { 636 if ($("body").hasClass("rtl")) { 637 $(".alice-carousel").css("direction", "ltr"); 638 setTimeout(function () { 639 // assuming the carousel exposes a refresh method 640 $(".alice-carousel").each(function () {
641 $(this).data("aliceCarousel")?.update(); 642 }); 643 }, 500); 644 } 645 }, 646 video_link: function ($this) { 647 let videoId = $this.data("video-url"); 648 if (videoId) { 649 let videoUrl = 650 videoId + (videoId.includes("?") ? "&" : "?") + "autoplay=1&mute=1"; 651 let iframe = $("<iframe>", { 652 id: "modalVideo", 653 width: "560", 654 height: "315", 655 frameborder: "0", 656 allow: "autoplay", 657 allowfullscreen: true, 658 src: videoUrl, 659 }); 660 $("#videoModalFrame").html(iframe); 661 $("#videoModal").fadeIn(); 662 } 663 }, 664 video_link_close: function (e) { 665 if ($(e.target).is("#videoModal") || $(e.target).is(".close")) { 666 $("#videoModal").fadeOut(); 667 $("#videoModalFrame").empty(); // Clear the iframe 668 } 669 }, 670 isSafari: function () { 671 return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 672 }, 673 toggle_line_label_chk: function ($this) { 674 const _label = $this.parent("label"); 675 if (_label) { 676 _label.toggleClass("highlight", this.checked); 677 } 678 return true; 679 }, 680 show_loader: function (bool) { 681 let _pre = $(".pre_loader_global"); 682 if (bool === true) { 683 _pre.removeClass("cj_hidden").show(); 684 } else { 685 setTimeout(function () { 686 _pre.addClass("cj_hidden").hide(); 687 }, 1000); 688 } 689 return true; 690 }, 691 }; 692 _general.init(); 693 694 const _cursor_spinner = { 695 activeRequests: 0, 696 init: function () { 697 const _self = this; 698 $(document).ajaxSend(function (_event, jqXHR, settings) { 699 if (!_self.is_add_to_cart_request(settings)) { 700 return; 701 } 702 _self.start(); 703 jqXHR.always(function () { 704 _self.stop(); 705 }); 706 }); 707 }, 708 supports_pointer_spinner: function () { 709 if (typeof window.matchMedia !== "function") { 710 return true; 711 } 712 return window.matchMedia("(pointer: fine)").matches; 713 }, 714 is_add_to_cart_request: function (settings) { 715 if (!settings) { 716 return false; 717 } 718 const data = settings.data; 719 if (typeof data === "string") { 720 return /(?:^|&)action=maimon_ajax_add_to_cart(?:&|$)/.test(data); 721 } 722 if (data instanceof URLSearchParams) { 723 return data.get("action") === "maimon_ajax_add_to_cart"; 724 } 725 return !!(data && data.action === "maimon_ajax_add_to_cart"); 726 }, 727 start: function () { 728 if (!this.supports_pointer_spinner()) { 729 return; 730 } 731 this.activeRequests += 1; 732 $("body").addClass("maimon-cursor-spinner-active"); 733 }, 734 stop: function () { 735 if (!this.supports_pointer_spinner()) { 736 return; 737 } 738 this.activeRequests = Math.max(0, this.activeRequests - 1); 739 if (this.activeRequests > 0) { 740 return; 741 } 742 $("body").removeClass("maimon-cursor-spinner-active"); 743 }, 744 }; 745 _cursor_spinner.init(); 746 747 $(document).on( 748 "click", 749 ".single_recipe_video_toggle,.single_page_guide_video_toggle", 750 function (e) { 751 e.preventDefault(); 752 _single.toggle_video($(this)); 753 }, 754 ); 755 $(document).on("click", ".float_ingredients_wrap_btn", function (e) { 756 e.preventDefault(); 757 _single.toggle_sidebar_ingredients($(this)); 758 }); 759 $(document).on("click", ".sidebar_ingredients", function (e) { 760 e.preventDefault(); 761 _single.toggle_sidebar_ingredients_block(e, $(this)); 762 }); 763 $(window).on("scroll resize", function () { 764 if ($(window).width() > 768) { 765 _single.sticky(); 766 _single.reset_sticky_btn(); 767 } else { 768 _single.reset_sticky(); 769 _single.sticky_btn(); 770 } 771 }); 772 $(document).on("click", ".in_post_maimon_video_line", function (e) { 773 e.preventDefault(); 774 _admin_op.selected_poster($(this)); 775 }); 776 777 const offsetTop = 50; // spacing from top 778 let isFixed = false;
779 let isBottomFixed = false; 780 const $floatBox = $(".float_ingredients_wrap"); 781 const $srpwmsi = $(".single_recipe_page_wrap_main_sidebar_inner"); // The div that follows scroll 782 const $srpwms = $(".single_recipe_page_wrap_main_sidebar"); 783 const $srpwmb = $(".single_recipe_page_wrap_main_body"); 784 let startPositionBtn, stopPositionBtn; 785 const _single = { 786 init: function () { 787 //this.sticky(); 788 if ( 789 $floatBox && 790 $floatBox.length > 0 && 791 $floatBox.parent() && 792 $floatBox.parent().length > 0 793 ) { 794 startPositionBtn = $floatBox.parent().offset().top; // Get the initial top position 795 stopPositionBtn = 796 $floatBox.parent().offset().top + 797 $floatBox.parent().outerHeight() - 798 $floatBox.outerHeight() - 799 offsetTop; 800 } 801 this.maybeShowYoutubePoster(); 802 }, 803 maybeShowYoutubePoster: function () { 804 const _class_target = $(".show_youtube_poster"); 805 const _vid_target = $("#recipeVideoFrame"); 806 if ( 807 _vid_target && 808 _vid_target.length > 0 && 809 _class_target && 810 _class_target.length > 0 811 ) { 812 const poster = $(".youtube_original_poster"); 813 const videoId = this.extractYouTubeVideoId( 814 _vid_target.attr("data-src"), 815 ); 816 const thumbnailUrl = `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`; 817 poster.attr("src", thumbnailUrl); 818 } 819 }, 820 selected_poster: function ($this) { 821 let $poster = $this.find(".in_post_maimon_video_poster"); 822 let $playIcon = $this.find(".in_post_maimon_video_play_icon"); 823 let $video = $this.find(".in_post_maimon_video"); 824 if ($video.css("display") === "none") { 825 $video.show().get(0).play(); 826 $poster.hide(); 827 $playIcon.hide(); 828 } 829 }, 830 toggle_video: function ($this) { 831 const target = $("#" + $this.attr("aria-controls")); 832 const _placehodler = $(".black_img_placeholder img"); 833 if (target && target.length > 0) { 834 if ($this.attr("data-type") === "external") { 835 this.play_iframe($this, target); 836 } else { 837 this.play_video($this, target); 838 } 839 } 840 if (_placehodler && _placehodler.length > 0) { 841 _placehodler.hide(); 842 } 843 return true; 844 }, 845 play_iframe: function ($this, target) { 846 if (typeof YT === "undefined" || typeof YT.Player === "undefined") { 847 console.warn("YouTube API not loaded yet."); 848 return; // prevent error if API is not ready 849 } 850 const videoId = this.extractYouTubeVideoId(target.attr("data-src")); 851 if (!$this.hasClass("active")) { 852 const _id = target.attr("id"); 853 target.html('<div id="' + _id + '_iframe"></div>'); 854 $(".black_img_placeholder img").fadeOut(300); 855 target.show(); 856 ytPlayer = new YT.Player(_id + "_iframe", { 857 videoId: videoId, 858 width: "100%", 859 height: "100%", 860 playerVars: { 861 autoplay: 1, 862 rel: 0, 863 }, 864 events: { 865 onReady: function (event) { 866 event.target.playVideo(); 867 }, 868 }, 869 }); 870 $this.hide(); 871 $this.addClass("active"); 872 } 873 }, 874 play_video: function ($this, target) { 875 if (target.length > 0) { 876 target.get(0).play(); 877 $this.hide(); 878 $this.addClass("active"); 879 target.on("play", function () { 880 $this.hide(); // Ensure it stays hidden when playing 881 }); 882 target.on("ended pause", function () { 883 if (target.get(0).paused) { 884 $this.show(); 885 $this.removeClass("active"); 886 } 887 }); 888 } 889 }, 890 monitorYouTubeStop: function (iframe, $button) { 891 if (typeof YT === "undefined" || typeof YT.Player === "undefined") { 892 var tag = document.createElement("script"); 893 tag.src = "https://www.youtube.com/iframe_api"; 894 var firstScriptTag = document.getElementsByTagName("script")[0]; 895 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 896 } 897 const videoId = new URL(iframe.attr("src")).searchParams.get("v"); 898 const player = new YT.Player(iframe[0], { 899 videoId: videoId, 900 events: { 901 onStateChange: function (event) { 902 if (event.data === YT.PlayerState.PLAYING) { 903 $button.hide(); 904 } else if ( 905 event.data === YT.PlayerState.ENDED || 906 event.data === YT.PlayerState.PAUSED 907 ) { 908 $button.show(); 909 $button.removeClass("active"); 910 } 911 }, 912 }, 913 }); 914 }, 915 monitorVimeoStop: function (iframe, $button) { 916 const player = new Vimeo.Player(iframe[0]); 917 player.on("play", function () { 918 $button.hide(); 919 }); 920 player.on("pause", function () { 921 $button.show(); 922 $button.removeClass("active"); 923 }); 924 player.on("ended", function () { 925 $button.show(); 926 $button.removeClass("active"); 927 }); 928 }, 929 extractYouTubeVideoId: function (url) { 930 let videoId = null; 931 const regexList = [ 932 /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/, 933 /youtu\.be\/([a-zA-Z0-9_-]{11})/, 934 /youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/, 935 /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/, 936 ]; 937 regexList.some((regex) => { 938 const match = url.match(regex); 939 if (match && match[1]) { 940 videoId = match[1]; 941 return true; 942 } 943 return false;
944 }); 945 if (!videoId && /^[a-zA-Z0-9_-]{11}$/.test(url)) { 946 videoId = url; 947 } 948 return videoId; 949 }, 950 sticky: function () { 951 let windowScroll = $(window).scrollTop(); 952 if ($srpwms && $srpwms.length > 0) { 953 let rightOffsetTop = $srpwms.offset().top; // Sidebar initial position 954 let leftOffsetTop = $srpwmb.offset().top; // Content top position 955 let leftHeight = $srpwmb.outerHeight(); 956 let rightHeight = $srpwmsi.outerHeight(); 957 let rightWidth = $srpwms.outerWidth(); 958 let stopPosition = leftOffsetTop + leftHeight - rightHeight; // Bottom limit 959 if (windowScroll >= stopPosition - offsetTop) { 960 $srpwmsi.css({ 961 position: "absolute", 962 top: leftHeight - rightHeight + "px", 963 width: rightWidth + "px", 964 }); 965 isFixed = false; // Stop being fixed 966 } else if (windowScroll > rightOffsetTop - offsetTop) { 967 if (!isFixed) { 968 $srpwmsi.css({ 969 position: "fixed", 970 top: offsetTop + "px", 971 width: rightWidth + "px", 972 }); 973 isFixed = true; 974 } 975 } else { 976 $srpwmsi.css({ 977 position: "relative", 978 top: "auto", 979 width: "auto", 980 }); 981 isFixed = false; 982 } 983 } 984 }, 985 sticky_btn: function () { 986 if ($floatBox && $floatBox.length > 0 && stopPositionBtn) { 987 let scrollY = $(window).scrollTop(); 988 if (scrollY >= startPositionBtn && scrollY < stopPositionBtn) { 989 if (_is_rtl) { 990 $floatBox.css({ 991 position: "fixed", 992 bottom: offsetTop + "px", 993 left: 0, 994 top: "auto!important", 995 }); 996 } else { 997 $floatBox.css({ 998 position: "fixed", 999 bottom: offsetTop + "px", 1000 right: 0, 1001 top: "auto!important", 1002 }); 1003 } 1004 } else if (scrollY >= stopPositionBtn) { 1005 if (_is_rtl) { 1006 $floatBox.css({ 1007 position: "absolute", 1008 bottom: 1009 $floatBox.parent().outerHeight() - 1010 $floatBox.parent().outerHeight() + 1011 offsetTop + 1012 "px", 1013 left: -20 + "px", 1014 top: "auto!important", 1015 }); 1016 } else { 1017 $floatBox.css({ 1018 position: "absolute", 1019 bottom: 1020 $floatBox.parent().outerHeight() - 1021 $floatBox.parent().outerHeight() + 1022 offsetTop + 1023 "px", 1024 right: -20 + "px", 1025 top: "auto!important", 1026 }); 1027 } 1028 } else { 1029 if (_is_rtl) { 1030 $floatBox.css({ 1031 position: "absolute", 1032 bottom: "20%", 1033 left: -20 + "px", 1034 top: "auto!important", 1035 }); 1036 } else { 1037 $floatBox.css({ 1038 position: "absolute", 1039 bottom: "20%", 1040 right: -20 + "px", 1041 top: "auto!important", 1042 }); 1043 } 1044 } 1045 } 1046 }, 1047 reset_sticky: function () { 1048 $srpwmsi.css({ 1049 position: "relative", 1050 bottom: "auto", 1051 width: "auto", 1052 }); 1053 isFixed = false; 1054 }, 1055 reset_sticky_btn: function () { 1056 $floatBox.css({ 1057 position: "relative", 1058 top: "auto", 1059 width: "auto", 1060 }); 1061 isFixed = false; 1062 }, 1063 toggle_sidebar_ingredients_block: function (e, $this) { 1064 if ($(e.target).closest(".sidebar_ingredients_inner").length === 0) { 1065 const _btn = $this.find(".float_ingredients_wrap_btn"); 1066 if (_btn && _btn.length > 0) { 1067 this.toggle_sidebar_ingredients(_btn); 1068 } 1069 } 1070 }, 1071 toggle_sidebar_ingredients: function ($this) { 1072 const _role = $this.attr("data-role"); 1073 const _target = $("#" + $this.attr("aria-controls")); 1074 if (_target && _target.length > 0) { 1075 const _opp = $($this.attr("data-opp")); 1076 if (_is_rtl) { 1077 if (_role === "open") { 1078 _target.animate({ left: "0" }, 500); 1079 } else { 1080 _target.animate({ left: "-100%" }, 500); 1081 } 1082 } else { 1083 if (_role === "open") { 1084 _target.animate({ right: "0" }, 500); 1085 } else { 1086 _target.animate({ right: "-100%" }, 500); 1087 } 1088 } 1089 $this.parent().fadeOut(500); 1090 _opp.parent().fadeIn(500); 1091 } 1092 return true; 1093 }, 1094 };
1095 _single.init(); 1096 1097 $(document).on("change", ".company_taxonomy_filter", function (e) { 1098 e.preventDefault(); 1099 _shop.filter_shop_by_company($(this)); 1100 }); 1101 const _shop = { 1102 filter_shop_by_company: function ($this) { 1103 let selectedCompanies = []; 1104 $(".company_taxonomy_filter:checked").each(function () { 1105 selectedCompanies.push($(this).val()); 1106 }); 1107 let queryString = selectedCompanies.length 1108 ? "?custom_category=" + selectedCompanies.join(",") 1109 : ""; 1110 let redirectUrl = 1111 window.location.origin + window.location.pathname + queryString; 1112 // Redirect to new URL 1113 window.location.href = redirectUrl; 1114 }, 1115 }; 1116 1117 $(document).on( 1118 "click", 1119 ".archive_posts_filter .category_filter", 1120 function (e) { 1121 e.preventDefault(); 1122 _archive.toggle_filter_category($(this)); 1123 }, 1124 ); 1125 $(document).on( 1126 "click", 1127 ".archive_posts_filter .company_filter", 1128 function (e) { 1129 e.preventDefault(); 1130 _archive.toggle_filter_company($(this)); 1131 }, 1132 ); 1133 $(document).on("click", "#customSortDropdown", function (e) { 1134 e.preventDefault(); 1135 _archive.toggle_options($(this)); 1136 }); 1137 $(document).on( 1138 "click", 1139 "#customSortDropdown #optionsList li button", 1140 function (e) { 1141 e.preventDefault(); 1142 _archive.select_option($(this)); 1143 }, 1144 ); 1145 $(document).on( 1146 "click", 1147 ".archive_posts_filter .load-more-btn", 1148 function (e) { 1149 e.preventDefault(); 1150 _archive.load_more($(this)); 1151 }, 1152 ); 1153 1154 $(document).on("click", function (e) { 1155 if (!$(e.target).closest($("#customSortDropdown")).length) { 1156 $("#optionsList").slideUp(); 1157 $("#customSortDropdown").removeClass("active"); 1158 } 1159 }); 1160 1161 const _archive = { 1162 debounceTimer: null, 1163 init: function () {}, 1164 toggle_filter_category: function ($this) { 1165 if ($this.hasClass("active")) { 1166 $this.removeClass("active"); 1167 } else { 1168 $this.addClass("active"); 1169 } 1170 if (!$this.hasClass("category")) { 1171 $(".archive_posts_filter").removeClass("active"); 1172 } 1173 this.archive_posts_filter(); 1174 }, 1175 toggle_filter_company: function ($this) { 1176 const _parent = $(".lobby_companies"); 1177 const active = $this.hasClass("active"); 1178 $(".archive_posts_filter .company_filter").removeClass("active"); 1179 if (!active) { 1180 $this.addClass("active"); 1181 } 1182 // clear al categories 1183 $.each($(".category_filter.active"), function (k, v) { 1184 $(this).removeClass("active"); 1185 }); 1186 if (!active) { 1187 this.archive_categories_display($this); 1188 } else { 1189 this.archive_categories_display($this, true); 1190 } 1191 this.archive_posts_filter(); 1192 if ($(".company_filter.active").length > 0) { 1193 _parent.addClass("active_lobby"); 1194 } else { 1195 _parent.removeClass("active_lobby"); 1196 } 1197 }, 1198 toggle_options: function ($this) { 1199 $("#optionsList").slideToggle(); 1200 $this.toggleClass("active"); 1201 }, 1202 select_option: function ($this) { 1203 if ($this.hasClass("active")) { 1204 return; 1205 } 1206 $("#selectedOption").text($this.text()); 1207 $("#customSortDropdown #optionsList li button").removeClass("active"); 1208 $this.addClass("active"); 1209 //toggle categories display for archive 1210 this.archive_posts_filter(); 1211 }, 1212 load_more: function ($this) { 1213 const page = $this.data("page") + 1; 1214 $this.data("page", page); 1215 this.archive_posts_filter(true, page); 1216 return true; 1217 }, 1218 archive_categories_display: function ($this, clear = false) { 1219 const _company = $this.attr("data-company"); 1220 const _post_type = $this.attr("data-post_type"); 1221 let _all = "0"; 1222 if (clear === true) { 1223 _all = "1"; 1224 } 1225 const _d = { 1226 action: "maimon_get_categories_ajax", 1227 post_type: _post_type, 1228 company: _company, 1229 nonce: _nonce, 1230 all: _all, 1231 }; 1232 this.ajax(_d, "POST", "display_categories"); 1233 }, 1234 archive_posts_filter: function ( 1235 load_more = false, 1236 page = 1, 1237 clear_terms = false, 1238 ) { 1239 const post_type = $(".archive_posts_filter").data("post-type"); 1240 const search = $('.archive_posts_filter input[type="search"]').val();
1241 const company = $(".company_filter.active").data("company"); 1242 const orderby = $("#optionsList button.active").data("orderby"); 1243 const order = $("#optionsList button.active").data("order"); 1244 const is_shop = $(".maimon_products_page").data("shop"); 1245 let categories = []; 1246 $.each($(".category_filter.active"), function (k, v) { 1247 categories.push($(v).data("category")); 1248 }); 1249 const _d = { 1250 action: "maimon_archive_posts_filter", 1251 post_type: post_type, 1252 search: search, 1253 categories: categories, 1254 company: company, 1255 orderby: orderby, 1256 order: order, 1257 page: page, 1258 is_shop: is_shop, 1259 nonce: _nonce, 1260 shop_page: $(".lobby_posts").attr("data-shop-page"), 1261 }; 1262 clearTimeout(this.debounceTimer); 1263 const _fv = this; 1264 this.debounceTimer = setTimeout(() => { 1265 _fv.ajax(_d, "POST", "filter", load_more); 1266 }, 300); 1267 return true; 1268 }, 1269 ajax: function (_data, method, callback, load_more) { 1270 $.ajax({ 1271 url: _ajax_url, 1272 data: _data, 1273 dataType: "json", 1274 method: method, 1275 success: function (response) { 1276 if (callback === "filter") { 1277 if (load_more) { 1278 $(".lobby_posts").append(response.data.html); 1279 } else { 1280 if (true === response.success) { 1281 $(".lobby_posts").html(response.data.html); 1282 } else { 1283 $(".lobby_posts").html( 1284 "<p>" + response.data.message + "</p>", 1285 ); 1286 } 1287 } 1288 if (response.data.load_more) { 1289 $(".load-more-btn").show(); 1290 } else { 1291 $(".load-more-btn").hide(); 1292 } 1293 } else if (callback === "display_categories") { 1294 if (response.data.status === "success" && response.data.terms) { 1295 const _terms_ids = []; 1296 $.each(response.data.terms, function (k, v) { 1297 if (v.has_company_posts === "1") { 1298 _terms_ids.push(v.term_id); 1299 } 1300 }); 1301 const _target = $(".lobby_categories .lobby_categories__items"); 1302 $.each(_target.find("button"), function () { 1303 let categoryId = $(this).data("category"); 1304 if ($.inArray(parseInt(categoryId), _terms_ids) !== -1) { 1305 $(this).attr("data-has_posts", "1"); 1306 } else { 1307 $(this).attr("data-has_posts", "0"); 1308 } 1309 }); 1310 } 1311 } 1312 }, 1313 }); 1314 }, 1315 }; 1316 1317 const _shortcodes = { 1318 init: function () { 1319 // run carousel 1320 const _g_r = $(".slick-slider"); 1321 if (_g_r && _g_r.length > 0) { 1322 _g_r.on( 1323 "init reInit afterChange", 1324 function (event, slick, currentSlide) { 1325 const $slider = $(event.currentTarget); 1326 $slider 1327 .find(".slick-slide") 1328 .attr("aria-hidden", "true") 1329 .attr("inert", "true"); // Hide all slides in this slider 1330 $slider 1331 .find(".slick-active") 1332 .attr("aria-hidden", "false") 1333 .removeAttr("inert"); // Show all visible slides in this slider 1334 }, 1335 ); 1336 } 1337 this.run_carousel_tips(); 1338 this.run_product_samples_tips(); 1339 this.run_carousel_chefs(); 1340 this.run_carousel_shop_products(); 1341 this.rerender_home_page_chef_area(); 1342 }, 1343 run_carousel_shop_products: function () { 1344 const _tr = $(".maimon_products_cases_inner_carousel_list"); 1345 if (_tr && _tr.length > 0) { 1346 const _max = 3; 1347 if (_tr.find("li").length >= _max) { 1348 // Mobile: Enable Slick Carousel 1349 if ($(window).width() < 980) { 1350 if (!_tr.hasClass("slick-initialized")) { 1351 let _args = { 1352 infinite: true, 1353 slidesToShow: 3, // Default (for large screens) 1354 slidesToScroll: 1, 1355 autoplay: true, 1356 autoplaySpeed: 2000,
1357 arrows: false, 1358 dots: false, 1359 centerMode: false, 1360 adaptiveHeight: true, 1361 responsive: [ 1362 { 1363 breakpoint: 768, // Below 780px 1364 settings: { 1365 slidesToShow: 2, 1366 }, 1367 }, 1368 { 1369 breakpoint: 480, // Below 480px 1370 settings: { 1371 slidesToShow: 1.5, 1372 }, 1373 }, 1374 { 1375 breakpoint: 420, // Below 400px 1376 settings: { 1377 slidesToShow: 1, 1378 }, 1379 }, 1380 ], 1381 }; 1382 if (_is_rtl) { 1383 _args.rtl = true; 1384 } 1385 _tr.slick(_args); 1386 } 1387 } 1388 // Desktop: Destroy Slick Carousel 1389 else { 1390 if (_tr.hasClass("slick-initialized")) { 1391 _tr.slick("unslick"); 1392 } 1393 } 1394 } 1395 } 1396 }, 1397 run_product_samples_tips: function () { 1398 const _tr = $(".maimon_products_may_like_inner_carousel_list"); 1399 if (_tr && _tr.length > 0) { 1400 const _max = 4; 1401 if (_tr.find("li").length >= _max) { 1402 // Mobile: Enable Slick Carousel 1403 if ($(window).width() < 1024) { 1404 if (!_tr.hasClass("slick-initialized")) { 1405 let _args = { 1406 infinite: true, 1407 slidesToShow: 4, // Default (for large screens) 1408 slidesToScroll: 1, 1409 autoplay: true, 1410 autoplaySpeed: 2000, 1411 arrows: false, 1412 dots: false, 1413 centerMode: false, 1414 adaptiveHeight: true, 1415 responsive: [ 1416 { 1417 breakpoint: 768, // Below 780px 1418 settings: { 1419 slidesToShow: 3, 1420 }, 1421 }, 1422 { 1423 breakpoint: 480, // Below 480px 1424 settings: { 1425 slidesToShow: 2, 1426 }, 1427 }, 1428 { 1429 breakpoint: 400, // Below 400px 1430 settings: { 1431 slidesToShow: 1, 1432 }, 1433 }, 1434 ], 1435 }; 1436 if (_is_rtl) { 1437 _args.rtl = true; 1438 } 1439 _tr.slick(_args); 1440 } 1441 } 1442 // Desktop: Destroy Slick Carousel 1443 else { 1444 if (_tr.hasClass("slick-initialized")) { 1445 _tr.slick("unslick"); 1446 } 1447 } 1448 } 1449 } 1450 }, 1451 run_carousel_chefs: function () { 1452 const _chefs = $("#maimon_chefs_list_inner_wrap_list"); 1453 if (_chefs && _chefs.length > 0) { 1454 const _max = 6; 1455 if (_chefs.find("li").length >= _max) { 1456 // Mobile: Enable Slick Carousel 1457 if ($(window).width() <= 768) { 1458 if (!_chefs.hasClass("slick-initialized")) { 1459 let _args = { 1460 infinite: true, 1461 slidesToShow: 6, // Default (for large screens) 1462 slidesToScroll: 2, 1463 autoplay: true, 1464 autoplaySpeed: 2000, 1465 arrows: false, 1466 dots: false, 1467 centerMode: false, 1468 adaptiveHeight: true, 1469 responsive: [ 1470 { 1471 breakpoint: 768, // Below 780px 1472 settings: { 1473 slidesToShow: 4, 1474 }, 1475 }, 1476 { 1477 breakpoint: 480, // Below 480px 1478 settings: { 1479 slidesToShow: 3, 1480 }, 1481 }, 1482 ], 1483 }; 1484 if (_is_rtl) { 1485 _args.rtl = true; 1486 } 1487 _chefs.slick(_args); 1488 } 1489 } 1490 // Desktop: Destroy Slick Carousel
1491 else { 1492 if (_chefs.hasClass("slick-initialized")) { 1493 _chefs.slick("unslick"); 1494 } 1495 } 1496 } 1497 } 1498 }, 1499 run_carousel_tips: function () { 1500 const _tr = $(".maimon_shortcode_tips_inner_carousel"); 1501 if (_tr && _tr.length > 0) { 1502 const _max = 4; 1503 if ( 1504 _tr.find(".maimon_shortcode_tips_inner_carousel_item").length >= 1505 _max 1506 ) { 1507 // Mobile: Enable Slick Carousel 1508 if ($(window).width() < 1024) { 1509 if (!_tr.hasClass("slick-initialized")) { 1510 let _args = { 1511 infinite: true, 1512 slidesToShow: 4, // Default (for large screens) 1513 slidesToScroll: 1, 1514 autoplay: true, 1515 autoplaySpeed: 2000, 1516 arrows: false, 1517 dots: false, 1518 centerMode: true, 1519 adaptiveHeight: true, 1520 responsive: [ 1521 { 1522 breakpoint: 768, // Below 780px 1523 settings: { 1524 slidesToShow: 2, 1525 }, 1526 }, 1527 { 1528 breakpoint: 480, // Below 480px 1529 settings: { 1530 slidesToShow: 1, 1531 }, 1532 }, 1533 ], 1534 }; 1535 if (_is_rtl) { 1536 _args.rtl = true; 1537 } 1538 _tr.slick(_args); 1539 } 1540 } 1541 // Desktop: Destroy Slick Carousel 1542 else { 1543 if (_tr.hasClass("slick-initialized")) { 1544 _tr.slick("unslick"); 1545 } 1546 } 1547 } 1548 } 1549 }, 1550 rerender_home_page_chef_area: function () { 1551 const $list = $(".maimon_chefs_list_inner_wrap_list"); 1552 const $centerItem = $list.find(".center_chef_row"); 1553 if ($centerItem.length === 0) { 1554 return; 1555 } 1556 $centerItem.detach(); 1557 const $items = $list.children().not(".center_chef_row"); 1558 if ($(window).width() <= 768) { 1559 const total = $items.length; 1560 const midIndex = Math.floor(total / 2); 1561 $centerItem.insertBefore($items.eq(midIndex)); 1562 } else { 1563 const firstTop = $items.first().position().top; 1564 const $firstRowItems = $items.filter(function () { 1565 return $(this).position().top === firstTop; 1566 }); 1567 const count = $firstRowItems.length; 1568 const centerIndex = Math.floor(count / 2) - 1; 1569 $centerItem.insertBefore($firstRowItems.eq(centerIndex)); 1570 } 1571 }, 1572 }; 1573 _shortcodes.init(); 1574 // Removed: $(window).resize(function() {_shortcodes.init();}); - causes duplicate slider initialization 1575 1576 $(document).on("submit", ".ajax_add_to_cart", function (e) { 1577 e.preventDefault(); 1578 _woocommerce_custom.add_to_cart_submit($(this)); 1579 }); 1580 $(document).on("click", ".maimon_ajax_add_to_cart", function (e) { 1581 var $btn = $(this); 1582 /* Unified product card: productCardActions handles ALL .maimon-product-card â skip here */ 1583 if ( 1584 $btn.hasClass("maimon_single_ajax_add_to_cart") || 1585 $btn.closest(".single_product_add_to_cart, .maimon-product-card").length 1586 ) { 1587 return; 1588 } 1589 e.preventDefault(); 1590 _woocommerce_custom.add_to_cart_click($btn); 1591 }); 1592 1593 const _woocommerce_custom = { 1594 init: function () { 1595 this.relocate_single_product_media(); 1596 this.run_gallery(); 1597 this.run_icons_nutritions(); 1598 $(window) 1599 .off("resize.singleProductMedia") 1600 .on("resize.singleProductMedia", () => { 1601 this.relocate_single_product_media(); 1602 }); 1603 }, 1604 run_icons_nutritions: function () { 1605 const _tr = $(".maimon_single_product_nutritional_lines_inner"); 1606 if (_tr && _tr.length > 0) { 1607 const _max = 3; 1608 _tr.each(function () { 1609 const _slider = $(this); 1610 const _count = _slider.find("li").length; 1611 const _desktopSlides = Math.min(_count, 3); 1612 const _tabletSlides = Math.min(_count, 2.2); 1613 const _mobileSlides = Math.min(_count, 2.2); 1614 if (_count <= 1 || _slider.hasClass("slick-initialized")) { 1615 return; 1616 } 1617 const _wrapper = _slider.closest( 1618 ".maimon_single_product_nutritional_lines_slider_wrap", 1619 ); 1620 let _args = { 1621 infinite: true, 1622 slidesToShow: _desktopSlides, 1623 slidesToScroll: 1, 1624 autoplay: true, 1625 autoplaySpeed: 2400, 1626 pauseOnHover: true, 1627 pauseOnFocus: true, 1628 arrows: true, 1629 dots: false, 1630 centerMode: false, 1631 adaptiveHeight: true, 1632 draggable: true, 1633 swipe: true, 1634 touchMove: true, 1635 prevArrow: 1636 '<button type="button" class="maimon_nutritional_arrow maimon_nutritional_arrow_prev" aria-label="Previous nutritional items"><span aria-hidden="true"></span></button>', 1637 nextArrow: 1638 '<button type="button" class="maimon_nutritional_arrow maimon_nutritional_arrow_next" aria-label="Next nutritional items"><span aria-hidden="true"></span></button>', 1639 appendArrows: _wrapper, 1640 responsive: [ 1641 { 1642 breakpoint: 767, 1643 settings: { 1644 slidesToShow: _tabletSlides, 1645 arrows: true, 1646 }, 1647 }, 1648 { 1649 breakpoint: 480, 1650 settings: { 1651 slidesToShow: _mobileSlides, 1652 arrows: true, 1653 }, 1654 }, 1655 ], 1656 }; 1657 if (_is_rtl) { 1658 _args.rtl = true; 1659 } 1660 _slider.slick(_args); 1661 }); 1662 } 1663 }, 1664 run_gallery: function () { 1665 const _tr = $(".single_page_product_wrap_main_sidebar_inner_carousel:visible"); 1666 if (_tr && _tr.length > 0) { 1667 _tr.each(function () { 1668 const $gallery = $(this); 1669 if ($gallery.hasClass("slick-initialized")) { 1670 return; 1671 } 1672 let _args = { 1673 infinite: true, 1674 slidesToShow: 1, 1675 slidesToScroll: 1, 1676 autoplay: false,
1677 arrows: false, 1678 dots: true, 1679 centerMode: false, 1680 adaptiveHeight: true, 1681 }; 1682 if (_is_rtl) { 1683 _args.rtl = true; 1684 } 1685 $gallery.slick(_args); 1686 }); 1687 } 1688 }, 1689 relocate_single_product_media: function () { 1690 const $sidebar = $(".single_page_product_wrap_main_sidebar").first(); 1691 const $mobileTarget = $(".single_product_mobile_gallery_target").first(); 1692 const $origin = $(".single_page_product_sidebar_origin").first(); 1693 if (!$sidebar.length || !$mobileTarget.length || !$origin.length) { 1694 return; 1695 } 1696 const isMobile = window.matchMedia("(max-width: 900px)").matches; 1697 const previousNode = $sidebar.prev()[0] || null; 1698 if (isMobile && previousNode !== $mobileTarget[0]) { 1699 $mobileTarget.after($sidebar); 1700 } else if (!isMobile && previousNode !== $origin[0]) { 1701 $origin.after($sidebar); 1702 } 1703 const $gallery = $sidebar.find( 1704 ".single_page_product_wrap_main_sidebar_inner_carousel.slick-initialized", 1705 ); 1706 if ($gallery.length) { 1707 $gallery.slick("setPosition"); 1708 } 1709 }, 1710 add_to_cart_click: function ($this) { 1711 if ($this.prop("disabled")) return; 1712 const product_id = $this.attr("data-product_id"); 1713 var $qtyInput = $this 1714 .closest(".maimon-product-card__actions") 1715 .find(".qty-input"); 1716 const quantity = $qtyInput.length 1717 ? parseInt($qtyInput.val(), 10) || 1 1718 : 1; 1719 const nonce = $this.data("nonce") || _nonce; 1720 $this.prop("disabled", true).text(_words.adding); 1721 const _d = { 1722 product_id: product_id, 1723 quantity: quantity, 1724 nonce: nonce, 1725 action: "maimon_ajax_add_to_cart", 1726 }; 1727 this.maybe_add_header_counter(); 1728 this.ajax(_d, "POST", "add_to_cart", { button: $this }); 1729 return true; 1730 }, 1731 add_to_cart_submit: function (form) { 1732 const product_id = form.find('input[name="product_id"]').val(); 1733 const quantity = form.find('input[name="quantity"]').val(); 1734 const button = form.find(".ajax_add_to_cart_button"); 1735 button.prop("disabled", true).text(_words.adding); 1736 const _d = { 1737 product_id: product_id, 1738 quantity: quantity, 1739 nonce: _nonce, 1740 action: "maimon_ajax_add_to_cart", 1741 }; 1742 if (!product_id || quantity < 1) { 1743 alert(_words.cannot_add_to_cart); 1744 return false; 1745 } 1746 this.maybe_add_header_counter(); 1747 this.ajax(_d, "POST", "add_to_cart", { button: button }); 1748 return true; 1749 }, 1750 maybe_add_header_counter: function () { 1751 const _number = $( 1752 ".header-cart.elementor-menu-cart__toggle_button .cart-icon.woo_cart_fragments", 1753 ); 1754 if (_number && _number.length > 0) { 1755 const _span_target = _number.find(".maimon_cart_count"); 1756 if (!_span_target.length) { 1757 _number.prepend( 1758 '<span class="maimon_cart_count elementor-button-icon-qty">' + 1759 0 + 1760 "</span>", 1761 ); 1762 } 1763 } 1764 }, 1765 ajax: function (ajax_data, method, callback, args = {}) { 1766 const _fv = this; 1767 $.ajax({ 1768 url: _ajax_url, 1769 data: ajax_data, 1770 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 1771 contentType: "application/json; charset=utf-8", 1772 dataType: "json", 1773 type: method, 1774 beforeSend: function () { 1775 _general.show_loader(true); 1776 }, 1777 success: function (response) { 1778 _general.show_loader(false); 1779 1780 if ( 1781 response && 1782 (response.fragments || 1783 (callback === "add_to_cart" && response.success)) 1784 ) { 1785 _fv.handle_response(response, callback, args); 1786 } else if ( 1787 !(callback === "add_to_cart" && response && response.success) 1788 ) { 1789 console.error("Unexpected response:", response); 1790 } 1791 }, 1792 error: function (error) { 1793 _general.show_loader(false); 1794 console.error("AJAX Error:", error); 1795 }, 1796 complete: function () { 1797 if ($.active <= 1) { 1798 $("body").removeClass("maimon-cursor-spinner-active"); 1799 } 1800 }, 1801 }); 1802 }, 1803 handle_response: function (response, callback = "", args = {}) { 1804 if (callback === "add_to_cart") { 1805 args.button 1806 .prop("disabled", false) 1807 .removeClass("loading") 1808 .text(cjpg_ajax_obj.words.add_to_cart); 1809 var data = response && response.data ? response.data : response; 1810 var fragments = 1811 data && data.fragments 1812 ? data.fragments 1813 : response && response.fragments 1814 ? response.fragments 1815 : {}; 1816 var cartHash = 1817 data && data.cart_hash 1818 ? data.cart_hash 1819 : response && response.cart_hash 1820 ? response.cart_hash 1821 : ""; 1822 var isSuccess = !!( 1823 response && 1824 (response.success || (data && data.count !== undefined)) 1825 ); 1826 if (isSuccess && data && typeof data.count !== "undefined") { 1827 updateCartBadges(data.count); 1828 } 1829 if (Object.keys(fragments).length) { 1830 console.log("Updating cart fragments...", fragments); 1831 $.each(fragments, function (selector, html) { 1832 var $targets = $(selector); 1833 if (!$targets.length) { 1834 return; 1835 } 1836 $targets.each(function () { 1837 $(this).replaceWith(html); 1838 }); 1839 }); 1840 $(document.body).trigger("wc_fragments_refreshed"); 1841 } 1842 $(document.body).trigger("maimon_cart_updated", [ 1843 data && typeof data.count !== "undefined" 1844 ? numericCount 1845 : undefined, 1846 ]); 1847 $(document).trigger("maimon_product_added_to_cart"); 1848 $(document.body).trigger("maimon_product_added_to_cart"); 1849 $(document.body).trigger("added_to_cart", [ 1850 fragments, 1851 cartHash, 1852 args.button, 1853 ]); 1854 const _qnt = $(".ajax_add_to_cart #quantity"); 1855 const _add_res = $(".ajax_add_to_cart_response"); 1856 if (_qnt && _qnt.length > 0) { 1857 _qnt.val(1); 1858 if (_add_res && _add_res.length > 0) { 1859 _add_res.append( 1860 '<em class="temp_result">' + _words.added + "</em>", 1861 ); 1862 setTimeout(function () { 1863 _add_res.html(""); 1864 }, 2000); 1865 } 1866 } 1867 } 1868 }, 1869 }; 1870 _woocommerce_custom.init(); 1871 1872 $(document).on( 1873 "input keyup touchstart", 1874 ".maimon_search_autocomplete", 1875 function (e) { 1876 e.preventDefault(); 1877 _deep_search.do_search($(this)); 1878 }, 1879 ); 1880 $(document).on( 1881 "input keyup touchstart", 1882 ".maimon_search_autocomplete_page input.e-search-input", 1883 function (e) { 1884 e.preventDefault(); 1885 _deep_search.do_search_page($(this)); 1886 }, 1887 ); 1888 $(document).on( 1889 "input keyup touchstart", 1890 ".maimon_search_autocomplete_archive", 1891 function (e) { 1892 e.preventDefault(); 1893 _deep_search.do_search_archive($(this)); 1894 }, 1895 ); 1896 $(document).on("click", function (e) { 1897 _deep_search.maybe_remove_the_search_result_box(e); 1898 }); 1899 $(document).on( 1900 "submit", 1901 "#search_hero_shortcode,.search_header_area_form_global", 1902 function (e) { 1903 const $input = $(this).find('input[type="search"]'); 1904 if ($input && $input.length > 0) { 1905 const value = $input.val().trim(); 1906 if (value.length < 2) { 1907 e.preventDefault(); 1908 } 1909 } 1910 }, 1911 ); 1912 1913 const _deep_search = { 1914 debounceTimer: null, 1915 maybe_remove_the_search_result_box: function (event) { 1916 if ( 1917 !$(event.target).closest( 1918 ".maimon_search_autocomplete, .maimon_search_autocomplete_page, .maimon_search_autocomplete_archive, .search_results_box, .search_results_box_page, .search_results_box_archive, .maimon-search-dropdown", 1919 ).length 1920 ) { 1921 $( 1922 ".search_results_box, .search_results_box_page, .search_results_box_archive", 1923 ).html(""); 1924 $(".search_results_box_archive").removeClass("active"); 1925 $(".maimon-search-dropdown").hide().empty(); 1926 } 1927 }, 1928 do_search: function ($this, is_archive = false) { 1929 let $input = $this; 1930 let query = $input.val(); 1931 let $wrapper = $input.closest("form");
1932 let $spinner = $wrapper.find(".input_spinner"); 1933 let $resultsContainer = $input.next(".search_results_box"); 1934 clearTimeout(this.debounceTimer); 1935 if (query.length <= 2) { 1936 if ($resultsContainer) { 1937 $resultsContainer.html(""); 1938 $spinner.hide(); 1939 } 1940 return; 1941 } 1942 $spinner.show(); 1943 const _fv = this; 1944 this.debounceTimer = setTimeout(() => { 1945 if ($resultsContainer.length === 0) { 1946 $resultsContainer = $('<div class="search_results_box"></div>'); 1947 $input.after($resultsContainer); 1948 } 1949 const _d = { 1950 action: "maimon_deepSearch", 1951 search: query, 1952 type: is_archive ? "archive" : "normal", 1953 }; 1954 _fv.ajax(_d, "POST", $resultsContainer, $spinner); 1955 }, 500); 1956 }, 1957 do_search_page: function ($this) { 1958 let $input = $this; 1959 let query = $input.val(); 1960 let $wrapper = $input.closest(".form"); 1961 let $spinner = $wrapper.find(".input_spinner"); 1962 let $resultsContainer = $input 1963 .parents(".e-search-form") 1964 .next(".search_results_box_page"); 1965 if (query.length > 2) { 1966 if ($spinner.length === 0) {
1967 $spinner = $('<div class="input_spinner"></div>'); 1968 $input.after($spinner); 1969 } 1970 if ($resultsContainer.length === 0) { 1971 $resultsContainer = $( 1972 '<div class="search_results_box_page"></div>', 1973 ); 1974 $input.parents(".e-search-form").after($resultsContainer); 1975 } 1976 const _d = { 1977 action: "maimon_deepSearch", 1978 search: query, 1979 type: "page", 1980 }; 1981 this.ajax(_d, "POST", $resultsContainer, $spinner); 1982 } else { 1983 if ($resultsContainer) { 1984 $resultsContainer.html(""); 1985 $spinner.hide(); 1986 } 1987 } 1988 return true; 1989 }, 1990 do_search_archive: function ($this) { 1991 let $input = $this; 1992 let query = $input.val(); 1993 let $wrapper = $("#lobby_search_block"); 1994 let $spinner = $wrapper.find(".input_spinner"); 1995 let $resultsContainer = $(".search_results_box_archive"); 1996 if (query.length > 2) { 1997 $resultsContainer.addClass("active"); 1998 const _d = { 1999 action: "maimon_deepSearch", 2000 search: query, 2001 type: "archive", 2002 }; 2003 this.ajax(_d, "POST", $resultsContainer, $spinner); 2004 } else { 2005 if ($resultsContainer) { 2006 $resultsContainer.removeClass("active"); 2007 $resultsContainer.html(""); 2008 $spinner.hide(); 2009 } 2010 } 2011 return true; 2012 }, 2013 ajax: function (data, method, $resultsContainer, $spinner) { 2014 let ajax_data; 2015 ajax_data = data; 2016 ajax_data["nonce"] = _nonce; 2017 $.ajax({ 2018 url: _ajax_url, 2019 data: ajax_data, 2020 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 2021 contentType: "application/json; charset=utf-8", 2022 dataType: "html", 2023 type: method, 2024 beforeSend: function () { 2025 $spinner.show(); 2026 }, 2027 success: function (response) { 2028 $resultsContainer.html(response); 2029 }, 2030 complete: function () { 2031 $spinner.hide(); 2032 }, 2033 }); 2034 }, 2035 }; 2036 2037 // Checkout step handling moved to checkout-step-fix.js. 2038 // fix slider height issue // 2039 $(".slick-slider").on("setPosition", function () { 2040 setTimeout(_fix_slick_slider.setEqualHeightPerSlider, 100); 2041 }); 2042 $(window).on("resize", function () { 2043 setTimeout(_fix_slick_slider.setEqualHeightPerSlider, 100); 2044 // Re-run carousel functions on resize to toggle grid/slider 2045 _shortcodes.run_carousel_tips(); 2046 _shortcodes.run_product_samples_tips(); 2047 _shortcodes.run_carousel_chefs(); 2048 _shortcodes.run_carousel_shop_products(); 2049 }); 2050 const _fix_slick_slider = { 2051 setEqualHeightPerSlider: function () { 2052 $(".slick-slider").each(function () { 2053 let maxHeight = 0; 2054 let $slider = $(this); 2055 let $slides = $slider.find(".slick-slide"); 2056 $slides.each(function () { 2057 let thisHeight = $(this).outerHeight(); 2058 if (thisHeight > maxHeight) { 2059 maxHeight = thisHeight; 2060 } 2061 }); 2062 $slider.find(".slick-track").css("height", maxHeight + "px"); 2063 }); 2064 }, 2065 }; 2066 }); 2067 2068 // redirect to thank you page after cf7 submitted 2069 document.addEventListener("DOMContentLoaded", function () { 2070 document.querySelectorAll('input[name="page_url"]').forEach(function (el) { 2071 if (!el.value) el.value = window.location.href; 2072 }); 2073 }); 2074 $(document).on("wpcf7mailsent", function (e) { 2075 const $form = $(e.target); 2076 const url = $form.find('input[name="page_url"]').val(); 2077 // Priority 3: per-form map fallback 2078 if (url) { 2079 // small delay so analytics events can fire 2080 setTimeout(function () { 2081 window.location.assign(url); 2082 }, 500); 2083 } 2084 }); 2085})(jQuery); 2086 2087/* âââ MAIMON CUSTOM JS v1.0.7 âââ */ 2088/** 2089 * custom.js â Maimon Theme Custom JavaScript 2090 * Appended to the end of app.min.js 2091 * 2092 * Sections: 2093 * Task 2 â Brands mega menu hover (show/hide) 2094 * Task 3 â Dropdown with image (maimon-mega-dropdown) 2095 * Task 4 â Mini cart count badge (AJAX update) 2096 * Task 5 â Cart drawer (open/close, qty, remove, refresh) 2097 * Task 6 â Products filter sidebar (AJAX filter) 2098 * Task 8 â Product card qty buttons + AJAX add-to-cart 2099 * Task 11 â "You may also like" carousel custom arrows 2100 */ 2101(function ($) { 2102 "use strict"; 2103 2104 /* ========================================================== 2105 TASK 2 â Brands Mega Menu Horizontal (hover show/hide) 2106 ========================================================== */ 2107 var brandsMega = (function () { 2108 var $menuItem, $subMenu; 2109 var hideTimer = null; 2110 var DELAY = 150;
2110 // ms grace period before closing 2111 2112 function open() { 2113 clearTimeout(hideTimer); 2114 $menuItem.addClass("mega-hover"); 2115 $subMenu.addClass("is-visible"); 2116 } 2117 2118 function close() { 2119 hideTimer = setTimeout(function () { 2120 $menuItem.removeClass("mega-hover"); 2121 $subMenu.removeClass("is-visible"); 2122 }, DELAY); 2123 } 2124 2125 function init() { 2126 $menuItem = $("#menu-item-2142"); 2127 if (!$menuItem.length) return; 2128 2129 $subMenu = $menuItem.children(".sub-menu"); 2130 if (!$subMenu.length) return; 2131 2132 // Show/hide on hover (desktop only) 2133 $menuItem.on("mouseenter", open).on("mouseleave", close); 2134 $subMenu.on("mouseenter", open).on("mouseleave", close); 2135 } 2136 2137 return { init: init }; 2138 })(); 2139 2140 /* ========================================================== 2141 TASK 3 â Dropdown with Image (maimon-mega-dropdown) 2142 ========================================================== */ 2143 var megaDropdown = (function () { 2144 var DELAY = 150; 2145 2146 function init() { 2147 $(".maimon-mega-dropdown").each(function () { 2148 var $item = $(this); 2149 var $sub = $item.children(".sub-menu"); 2150 var timer = null; 2151 2152 if (!$sub.length) return; 2153 2154 // Populate image section from data-image attribute or first child image 2155 var imageUrl = $item.data("image") || ""; 2156 if (!imageUrl) { 2157 var $firstImg = $sub.find("img").first(); 2158 if ($firstImg.length) { 2159 imageUrl = $firstImg.attr("src"); 2160 } 2161 } 2162 2163 // If we have an image URL and no image container yet, prepend one 2164 if (imageUrl && !$sub.find(".mega-dropdown-image").length) { 2165 $sub.prepend( 2166 '<div class="mega-dropdown-image">' + 2167 '<img src="' + 2168 imageUrl + 2169 '" alt="" loading="lazy">' + 2170 "</div>", 2171 ); 2172 } 2173 2174 function openSub() { 2175 clearTimeout(timer); 2176 $item.addClass("mega-hover"); 2177 $sub.addClass("is-visible"); 2178 } 2179 2180 function closeSub() { 2181 timer = setTimeout(function () { 2182 $item.removeClass("mega-hover"); 2183 $sub.removeClass("is-visible"); 2184 }, DELAY); 2185 } 2186 2187 $item.on("mouseenter", openSub).on("mouseleave", closeSub); 2188 $sub.on("mouseenter", openSub).on("mouseleave", closeSub); 2189 }); 2190 } 2191 2192 return { init: init }; 2193 })(); 2194 2195 /* ========================================================== 2196 TASK 4 â Mini Cart Count Badge (AJAX update) 2197 ========================================================== */ 2198 function updateCartBadges(count) { 2199 var numericCount = Math.max(0, parseInt(count, 10) || 0); 2200 var $allBadges = $( 2201 ".maimon_cart_count, .elementor-button-icon-qty, #header-cart-btn .cart-badge, .maimon-cart-count", 2202 ); 2203 var $drawerBadges = $("#header-cart-btn .cart-badge, .maimon-cart-count"); 2204 2205 $allBadges.text(numericCount); 2206 2207 if ($drawerBadges.length) { 2208 $drawerBadges.toggleClass("has-items", numericCount > 0); 2209 $drawerBadges.css("display", numericCount > 0 ? "flex" : "none"); 2210 } 2211 } 2212 2213 window.maimonUpdateCartBadges = updateCartBadges; 2214 2215 var miniCartBadge = (function () { 2216 /** 2217 * Fetch the current cart count from the server 2218 * and update all `.maimon-cart-count` badges. 2219 */ 2220 function refreshCount(event, count) { 2221 if (typeof count !== "undefined" && count !== null) { 2222 updateCartBadges(count); 2223 return; 2224 } 2225 2226 if (typeof cjpg_ajax_obj === "undefined") return; 2227 2228 $.post( 2229 cjpg_ajax_obj.ajaxurl, 2230 { 2231 action: "maimon_get_cart_count", 2232 nonce: cjpg_ajax_obj.nonce, 2233 }, 2234 function (res) { 2235 if (res.success) { 2236 updateCartBadges(res.data.count); 2237 } 2238 }, 2239 ); 2240 } 2241 2242 function init() { 2243 // WooCommerce native events 2244 $(document.body).on("added_to_cart", syncProductCards); 2245 $(document.body).on("removed_from_cart", refreshCount); 2246 $(document.body).on("removed_from_cart", syncProductCards); 2247 2248 // Custom event fired by cart drawer and product card after mutations 2249 $(document.body).on("maimon_cart_updated", refreshCount); 2250 $(document.body).on("maimon_cart_updated", syncProductCards); 2251 } 2252 2253 return { init: init }; 2254 })(); 2255
2256 /* ââ Sync product cards on index/shop with cart quantities ââ */ 2257 function syncProductCards() { 2258 if (typeof cjpg_ajax_obj === "undefined") return; 2259 $.post( 2260 cjpg_ajax_obj.ajaxurl, 2261 { 2262 action: "maimon_get_cart_items", 2263 nonce: cjpg_ajax_obj.nonce, 2264 }, 2265 function (res) { 2266 if (!res || !res.success || !res.data || !res.data.items) return; 2267 var qtyByProduct = {}; 2268 $.each(res.data.items, function (i, it) { 2269 var pid = parseInt(it.product_id, 10); 2270 if (pid) 2271 qtyByProduct[pid] = 2272 (qtyByProduct[pid] || 0) + (parseInt(it.qty, 10) || 0); 2273 }); 2274 $(".maimon-product-card").each(function () { 2275 var $card = $(this); 2276 var $btn = $card.find(".maimon_ajax_add_to_cart"); 2277 var pid = $btn.length ? parseInt($btn.data("product_id"), 10) : 0; 2278 var $input = $card.find(".qty-input"); 2279 if (!pid || !$input.length) return; 2280 var qty = qtyByProduct[pid] || 0; 2281 if (qty > 0) { 2282 $card.addClass("maimon-product-card--in-cart"); 2283 $input.val(qty); 2284 $btn.attr("data-quantity", qty).data("quantity", qty).text(qty); 2285 } else { 2286 $card.removeClass("maimon-product-card--in-cart"); 2287 $input.val(1); 2288 var addLabel = 2289 typeof cjpg_ajax_obj !== "undefined" && 2290 cjpg_ajax_obj.words && 2291 cjpg_ajax_obj.words.add_to_cart 2292 ? cjpg_ajax_obj.words.add_to_cart 2293 : "\u05D4\u05D5\u05E1\u05E4\u05D4 \u05DC\u05E1\u05DC"; 2294 $btn.attr("data-quantity", 1).data("quantity", 1).text(addLabel); 2295 } 2296 }); 2297 2298 // Also sync single product page controls from cart state 2299 $(".single_product_add_to_cart .single-product-cart-row").each( 2300 function () { 2301 var $row = $(this); 2302 var pid = parseInt($row.data("product-id"), 10) || 0; 2303 if (!pid) return; 2304 var qty = qtyByProduct[pid] || 0; 2305 if (qty > 0) { 2306 $row 2307 .addClass("single-product-cart-row--in-cart") 2308 .attr("data-in-cart", "1"); 2309 $row.find(".single-product-qty-val").text(qty); 2310 } else { 2311 $row 2312 .removeClass("single-product-cart-row--in-cart") 2313 .attr("data-in-cart", "0"); 2314 $row.find(".single-product-qty-val").text(1); 2315 } 2316 }, 2317 ); 2318 }, 2319 ); 2320 } 2321 2322 /* ========================================================== 2323 TASK 5 â Cart Drawer (open/close, qty, remove, refresh) 2324 ========================================================== */ 2325 var cartDrawer = (function () { 2326 var $drawer, $overlay, $body, $footer; 2327 var isOpen = false; 2328 2329 /* ââ Open the drawer ââ */ 2330 function open() { 2331 if (isOpen) return; 2332 isOpen = true; 2333 $drawer.addClass("is-open").attr("aria-hidden", "false"); 2334 $overlay.addClass("is-visible"); 2335 $("body").addClass("maimon-cart-drawer-open"); 2336 // Focus the close button for accessibility 2337 $drawer.find(".maimon-cart-drawer__close").trigger("focus"); 2338 // Load / refresh drawer content 2339 refreshDrawer(); 2340 } 2341 2342 /* ââ Close the drawer ââ */ 2343 function close() { 2344 if (!isOpen) return; 2345 isOpen = false; 2346 $drawer.removeClass("is-open").attr("aria-hidden", "true"); 2347 $overlay.removeClass("is-visible"); 2348 $("body").removeClass("maimon-cart-drawer-open"); 2349 } 2350 2351 /* ââ Refresh drawer body + footer via AJAX ââ */ 2352 function refreshDrawer() { 2353 if (typeof cjpg_ajax_obj === "undefined") return; 2354 2355 $drawer.addClass("is-loading"); 2356 2357 $.post( 2358 cjpg_ajax_obj.ajaxurl, 2359 { 2360 action: "maimon_get_cart_drawer", 2361 nonce: cjpg_ajax_obj.nonce, 2362 }, 2363 function (res) { 2364 $drawer.removeClass("is-loading"); 2365 if (res.success) { 2366 $drawer 2367 .find(".maimon-cart-drawer__body") 2368 .html(res.data.body_html || ""); 2369 $drawer 2370 .find(".maimon-cart-drawer__footer") 2371 .html(res.data.footer_html || ""); 2372 var $countVal = $drawer.find(".maimon-cart-drawer__count-value"); 2373 if ($countVal.length && res.data.count !== undefined) { 2374 $countVal.text( 2375 res.data.count + 2376 " " + 2377 (res.data.count === 1 2378 ? "\u05E4\u05E8\u05D9\u05D8" 2379 : "\u05E4\u05E8\u05D9\u05D8\u05D9\u05DD"), 2380 ); 2381 } 2382 var $footerInner = $drawer.find( 2383 ".maimon-cart-drawer__footer-inner", 2384 ); 2385 if ($footerInner.length) { 2386 $footerInner.toggleClass("is-hidden", !!res.data.is_empty); 2387 } 2388 } 2389 }, 2390 ).fail(function () { 2391 $drawer.removeClass("is-loading"); 2392 }); 2393 } 2394 2395 /* ââ Update item quantity ââ */ 2396 function updateQty(cartItemKey, quantity) { 2397 if (typeof cjpg_ajax_obj === "undefined") return; 2398 2399 $.post( 2400 cjpg_ajax_obj.ajaxurl, 2401 { 2402 action: "maimon_update_cart_item", 2403 cart_item_key: cartItemKey, 2404 quantity: quantity, 2405 nonce: cjpg_ajax_obj.nonce, 2406 }, 2407 function (res) { 2408 if (res.success) { 2409 refreshDrawer(); 2410 $(document.body).trigger("maimon_cart_updated", [ 2411 res && res.data ? res.data.count : undefined, 2412 ]); 2413 return; 2414 } 2415 2416 refreshDrawer(); 2417 if (res && res.data && res.data.message) { 2418 window.alert(res.data.message); 2419 } 2420 }, 2421 ).fail(function () { 2422 refreshDrawer(); 2423 }); 2424 } 2425
2426 function clampQtyValue(value, $qtyInput) { 2427 var min = parseInt($qtyInput.attr("min"), 10) || 1; 2428 var max = parseInt($qtyInput.attr("max"), 10) || 99; 2429 var parsed = parseInt(value, 10); 2430 2431 if (isNaN(parsed)) { 2432 parsed = min; 2433 } 2434 2435 return Math.max(min, Math.min(parsed, max)); 2436 } 2437 2438 function applyDrawerQty($wrap, nextQty) { 2439 var key = $wrap.data("cart-item-key"); 2440 var $qty = $wrap.find(".qty-input").first(); 2441 2442 if (!key || !$qty.length) return; 2443 2444 var next = clampQtyValue(nextQty, $qty); 2445 var last = clampQtyValue($qty.attr("data-last-value"), $qty); 2446 2447 $qty.val(next); 2448 2449 if (next === last) return; 2450 2451 $qty.attr("data-last-value", next); 2452 updateQty(key, next); 2453 } 2454 2455 /* ââ Remove item ââ */ 2456 function removeItem(cartItemKey) { 2457 if (typeof cjpg_ajax_obj === "undefined") return; 2458 2459 $.post( 2460 cjpg_ajax_obj.ajaxurl, 2461 { 2462 action: "maimon_remove_cart_item", 2463 cart_item_key: cartItemKey, 2464 nonce: cjpg_ajax_obj.nonce, 2465 }, 2466 function (res) { 2467 if (res.success) { 2468 refreshDrawer(); 2469 $(document.body).trigger("maimon_cart_updated", [ 2470 res && res.data ? res.data.count : undefined, 2471 ]); 2472 } 2473 }, 2474 ); 2475 } 2476 2477 /* ââ Bind all events ââ */ 2478 function bindEvents() { 2479 // Open: cart icon click 2480 $(document).on("click", ".maimon-header-cart", function (e) { 2481 e.preventDefault(); 2482 open(); 2483 }); 2484 2485 // Open: custom event 2486 $(document.body).on("maimon_open_cart_drawer", function () { 2487 open(); 2488 }); 2489 2490 // Close: X button 2491 $(document).on("click", ".maimon-cart-drawer__close", function () { 2492 close(); 2493 }); 2494 2495 // Close: overlay click 2496 $(document).on("click", ".maimon-cart-drawer__overlay", function () { 2497 close(); 2498 }); 2499 2500 // Close: ×××©× ×§× ××× button 2501 $(document).on("click", ".maimon-cart-drawer__btn-continue", function () { 2502 close(); 2503 }); 2504 2505 // Close: ESC key 2506 $(document).on("keydown", function (e) { 2507 if (e.key === "Escape" && isOpen) { 2508 close(); 2509 } 2510 }); 2511 2512 // Qty plus button (delegated inside drawer) 2513 $(document).on( 2514 "click", 2515 '.maimon-cart-drawer .qty-btn[data-action="plus"]', 2516 function () { 2517 var $btn = $(this); 2518 var $wrap = $btn.closest(".maimon-cart-drawer__item"); 2519 var $qty = $wrap.find(".qty-input").first(); 2520 var cur = clampQtyValue($qty.val(), $qty); 2521 2522 applyDrawerQty($wrap, cur + 1); 2523 }, 2524 ); 2525 2526 // Qty minus button (delegated inside drawer) 2527 $(document).on( 2528 "click", 2529 '.maimon-cart-drawer .qty-btn[data-action="minus"]', 2530 function () { 2531 var $btn = $(this); 2532 var $wrap = $btn.closest(".maimon-cart-drawer__item"); 2533 var $qty = $wrap.find(".qty-input").first(); 2534 var cur = clampQtyValue($qty.val(), $qty); 2535 2536 applyDrawerQty($wrap, cur - 1); 2537 }, 2538 ); 2539 2540 // Qty direct input 2541 $(document).on("input", ".maimon-cart-drawer .qty-input", function () { 2542 var raw = String($(this).val() || "").replace(/[^\d]/g, ""); 2543 $(this).val(raw); 2544 }); 2545 2546 $(document).on("change", ".maimon-cart-drawer .qty-input", function () { 2547 applyDrawerQty( 2548 $(this).closest(".maimon-cart-drawer__item"), 2549 $(this).val(), 2550 ); 2551 }); 2552 2553 $(document).on("keydown", ".maimon-cart-drawer .qty-input", function (e) { 2554 if (e.key === "Enter") { 2555 e.preventDefault(); 2556 $(this).trigger("change"); 2557 $(this).trigger("blur"); 2558 } 2559 }); 2560 2561 // Remove item button 2562 $(document).on( 2563 "click", 2564 ".maimon-cart-drawer .maimon-cart-drawer__remove", 2565 function () { 2566 var $wrap = $(this).closest(".maimon-cart-drawer__item"); 2567 var key = $wrap.data("cart-item-key"); 2568 // Fade out the item optimistically 2569 $wrap.fadeOut(200); 2570 removeItem(key); 2571 }, 2572 ); 2573 } 2574
2575 function init() { 2576 $drawer = $(".maimon-cart-drawer"); 2577 $overlay = $(".maimon-cart-drawer__overlay"); 2578 $body = $(".maimon-cart-drawer__body"); 2579 $footer = $(".maimon-cart-drawer__footer"); 2580 2581 if (!$drawer.length) return; 2582 2583 bindEvents(); 2584 } 2585 2586 return { init: init }; 2587 })(); 2588 2589 /* ========================================================== 2590 TASK 6 â Products Filter Sidebar (AJAX filter + Load More) 2591 ========================================================== */ 2592 var productsFilter = (function () { 2593 var $panel, $grid, $count, $loadMoreWrap, $loadMoreBtn, $sortSelect; 2594 var currentOrder = "date"; 2595 var debounceTimer = null; 2596 var loadedCount = 0; 2597 var totalCount = 0; 2598 var INITIAL_PP = 16; 2599 var LOADMORE_PP = 8; 2600 2601 /* ââ Read URL search params ââ */ 2602 function getUrlParams() { 2603 var params = new URLSearchParams(window.location.search); 2604 var brands = params.getAll("brands[]").length 2605 ? params.getAll("brands[]") 2606 : params.getAll("brands"); 2607 var categories = params.getAll("categories[]").length 2608 ? params.getAll("categories[]") 2609 : params.getAll("categories"); 2610 var legacyCompanies = params.getAll("company"); 2611 var legacyCategories = params.getAll("product_category"); 2612 2613 legacyCompanies.forEach(function (company) { 2614 brands.push(company); 2615 }); 2616 legacyCategories.forEach(function (category) { 2617 categories.push(category); 2618 }); 2619 2620 return { 2621 search: params.get("search") || "", 2622 brands: Array.from(new Set(brands)), 2623 categories: Array.from(new Set(categories)), 2624 orderby: params.get("orderby") || "date", 2625 }; 2626 } 2627 2628 /* ââ Update URL without reload ââ */ 2629 function updateUrl() { 2630 var filters = getFilters(); 2631 var params = new URLSearchParams(); 2632 2633 if (filters.search) { 2634 params.set("search", filters.search); 2635 } 2636 filters.brands.forEach(function (b) { 2637 params.append("brands[]", b); 2638 }); 2639 filters.categories.forEach(function (c) { 2640 params.append("categories[]", c); 2641 }); 2642 if (currentOrder && currentOrder !== "date") { 2643 params.set("orderby", currentOrder); 2644 } 2645 2646 var qs = params.toString(); 2647 var newUrl = window.location.pathname + (qs ? "?" + qs : ""); 2648 window.history.replaceState(null, "", newUrl); 2649 } 2650 2651 /* ââ Collect checked brands, categories, search value ââ */ 2652 function getFilters() { 2653 var brands = []; 2654 var categories = []; 2655 2656 $panel.find('input[name="brands[]"]:checked').each(function () { 2657 brands.push($(this).val()); 2658 }); 2659 $panel.find('input[name="categories[]"]:checked').each(function () { 2660 categories.push($(this).val()); 2661 }); 2662 2663 return { 2664 search: $panel.find(".maimon-filter-search__input").val() || "", 2665 brands: brands, 2666 categories: categories, 2667 }; 2668 } 2669 2670 /* ââ Execute AJAX filter request ââ */ 2671 function doFilter(append) { 2672 var filters = getFilters(); 2673 var nonce = $panel.data("nonce") || ""; 2674 var ajaxUrl = 2675 typeof cjpg_ajax_obj !== "undefined" ? cjpg_ajax_obj.ajaxurl : ""; 2676 2677 if (!ajaxUrl) return; 2678 2679 var perPage = append ? LOADMORE_PP : INITIAL_PP; 2680 var offset = append ? loadedCount : 0; 2681 2682 $grid.addClass("maimon-loading"); 2683 if ($loadMoreBtn.length) { 2684 $loadMoreBtn.prop("disabled", true).text("\u05D8\u05D5\u05E2\u05DF..."); // "×××¢×..." 2685 } 2686 2687 if (!append) { 2688 updateUrl(); 2689 } 2690 2691 $.ajax({ 2692 url: ajaxUrl, 2693 type: "POST", 2694 data: { 2695 action: "maimon_filter_products", 2696 nonce: nonce, 2697 search: filters.search, 2698 brands: filters.brands, 2699 categories: filters.categories, 2700 orderby: currentOrder, 2701 per_page: perPage, 2702 offset: offset, 2703 }, 2704 success: function (res) { 2705 $grid.removeClass("maimon-loading"); 2706 if (res && res.success) { 2707 if (append) { 2708 $grid.append(res.data.html); 2709 } else { 2710 $grid.html(res.data.html); 2711 } 2712 totalCount = res.data.count; 2713 loadedCount = res.data.loaded; 2714 updateCount(totalCount); 2715 updateLoadMore(res.data.has_more); 2716 } 2717 if ($loadMoreBtn.length) { 2718 $loadMoreBtn 2719 .prop("disabled", false) 2720 .text( 2721 "\u05D8\u05E2\u05DF \u05E2\u05D5\u05D3 \u05DE\u05D5\u05E6\u05E8\u05D9\u05DD", 2722 ); // "××¢× ×¢×× ××צר××" 2723 } 2724 }, 2725 error: function () { 2726 $grid.removeClass("maimon-loading"); 2727 if ($loadMoreBtn.length) { 2728 $loadMoreBtn 2729 .prop("disabled", false) 2730 .text( 2731 "\u05D8\u05E2\u05DF \u05E2\u05D5\u05D3 \u05DE\u05D5\u05E6\u05E8\u05D9\u05DD", 2732 ); 2733 } 2734 }, 2735 }); 2736 } 2737 2738 /* ââ Update results count label ââ */ 2739 function updateCount(total) { 2740 if ($count.length) { 2741 $count.text( 2742 "\u05E0\u05DE\u05E6\u05D0\u05D5 \u05E1\u05D4\u05F4\u05DB \u05DB " + 2743 total + 2744 " \u05DE\u05D5\u05E6\u05E8\u05D9\u05DD", 2745 ); // "× ×צ×× ×¡××´× × {x} ××צר××" 2746 } 2747 } 2748 2749 /* ââ Show / hide load-more button ââ */ 2750 function updateLoadMore(hasMore) { 2751 if ($loadMoreWrap.length) { 2752 if (hasMore) { 2753 $loadMoreWrap.show(); 2754 } else { 2755 $loadMoreWrap.hide(); 2756 } 2757 } 2758 } 2759 2760 /* ââ Toggle accordion groups ââ */ 2761 function initAccordions() { 2762 $panel.on("click", ".maimon-filter-group__header", function () { 2763 var $header = $(this); 2764 var $body = $header.next(".maimon-filter-group__body"); 2765 var isOpen = $header.attr("aria-expanded") === "true"; 2766 2767 $header.attr("aria-expanded", isOpen ? "false" : "true"); 2768 2769 if (isOpen) {
2770 $body.slideUp(200, function () { 2771 $body.attr("hidden", ""); 2772 }); 2773 } else { 2774 $body.removeAttr("hidden").hide().slideDown(200); 2775 } 2776 }); 2777 } 2778 2779 /* ââ Debounced search input (400ms) ââ */ 2780 function initSearch() { 2781 $panel.on("input", ".maimon-filter-search__input", function () { 2782 clearTimeout(debounceTimer); 2783 debounceTimer = setTimeout(function () { 2784 doFilter(false); 2785 }, 400); 2786 }); 2787 } 2788 2789 /* ââ Checkbox change triggers filter ââ */ 2790 function initCheckboxes() { 2791 $panel.on("change", 'input[type="checkbox"]', function () { 2792 doFilter(false); 2793 }); 2794 } 2795 2796 /* ââ Sort dropdown change triggers filter ââ */ 2797 function initSort() { 2798 $sortSelect = $("#maimon-sort-select"); 2799 if ($sortSelect.length) { 2800 $sortSelect.on("change", function () { 2801 currentOrder = $(this).val(); 2802 doFilter(false); 2803 }); 2804 } 2805 } 2806 2807 /* ââ Load More button click ââ */ 2808 function initLoadMore() { 2809 $loadMoreBtn.on("click", function () { 2810 doFilter(true); 2811 }); 2812 } 2813 2814 /* ââ Apply URL params to UI on init ââ */ 2815 function applyUrlParams() { 2816 var params = getUrlParams(); 2817 function checkInputsByParam(name, values) { 2818 values.forEach(function (rawValue) { 2819 var value = String(rawValue); 2820 var $input = $panel.find( 2821 'input[name="' + name + '[]"][value="' + value + '"]', 2822 ); 2823 if (!$input.length) { 2824 $input = $panel 2825 .find('input[name="' + name + '[]"]') 2826 .filter(function () { 2827 return String($(this).data("termSlug")) === value; 2828 }) 2829 .first(); 2830 } 2831 if ($input.length) { 2832 $input.prop("checked", true); 2833 } 2834 }); 2835 } 2836 2837 if (params.search) { 2838 $panel.find(".maimon-filter-search__input").val(params.search); 2839 } 2840 2841 checkInputsByParam("brands", params.brands); 2842 checkInputsByParam("categories", params.categories); 2843 2844 if (params.orderby) { 2845 currentOrder = params.orderby; 2846 if ($sortSelect && $sortSelect.length) { 2847 $sortSelect.val(params.orderby); 2848 } 2849 } 2850 } 2851 2852 function init() { 2853 $panel = $(".maimon-filter-panel"); 2854 $grid = $(".maimon-products-grid"); 2855 $count = $(".maimon-results-count"); 2856 $loadMoreWrap = $(".maimon-load-more-wrap"); 2857 $loadMoreBtn = $(".maimon-load-more-btn"); 2858 2859 if (!$panel.length || !$grid.length) return; 2860 2861 initAccordions(); 2862 initSearch(); 2863 initCheckboxes(); 2864 initSort(); 2865 initLoadMore(); 2866 2867 applyUrlParams(); 2868 doFilter(false); 2869 } 2870 2871 return { init: init }; 2872 })(); 2873 2874 /* ========================================================== 2875 TASK 8 â Product Card Qty Buttons + AJAX Add-to-Cart 2876 ========================================================== */ 2877 var productCardActions = (function () { 2878 function init() { 2879 // Qty +/- buttons on product cards in grid 2880 $(document).on( 2881 "click", 2882 '.maimon-product-card .maimon-product-card__qty .qty-btn[data-action="plus"]', 2883 function () { 2884 if ( 2885 $(this).closest( 2886 ".single_product_add_to_cart, .maimon-cart-drawer, #side-cart-drawer", 2887 ).length 2888 ) 2889 return; 2890 var $input = $(this) 2891 .closest(".maimon-product-card__qty") 2892 .find(".qty-input"); 2893 var val = parseInt($input.val(), 10) || 1; 2894 var newVal = Math.min(val + 1, 99); 2895 $input.val(newVal); 2896 syncCartBtnQty($(this)); 2897 2898 // If card is in-cart, sync exact qty in cart 2899 var $card = $(this).closest(".maimon-product-card"); 2900 if ($card.hasClass("maimon-product-card--in-cart")) { 2901 setProductQtyInCart($card, newVal); 2902 } 2903 }, 2904 ); 2905 2906 $(document).on( 2907 "click", 2908 '.maimon-product-card .maimon-product-card__qty .qty-btn[data-action="minus"]', 2909 function () { 2910 if ( 2911 $(this).closest( 2912 ".single_product_add_to_cart, .maimon-cart-drawer, #side-cart-drawer", 2913 ).length 2914 ) 2915 return; 2916 var $input = $(this) 2917 .closest(".maimon-product-card__qty") 2918 .find(".qty-input"); 2919 var val = parseInt($input.val(), 10) || 1; 2920 var $card = $(this).closest(".maimon-product-card"); 2921 2922 // Before add-to-cart keep minimum 1 in UI. 2923 if (!$card.hasClass("maimon-product-card--in-cart")) { 2924 if (val <= 1) return; 2925 $input.val(val - 1); 2926 syncCartBtnQty($(this)); 2927 return; 2928 } 2929 2930 var newVal = Math.max(val - 1, 0); 2931 if (newVal === 0) { 2932 $card.removeClass("maimon-product-card--in-cart"); 2933 $input.val(1); 2934 syncCartBtnQty($(this)); 2935 setProductQtyInCart($card, 0); 2936 return; 2937 } 2938 2939 $input.val(newVal); 2940 syncCartBtnQty($(this)); 2941 setProductQtyInCart($card, newVal); 2942 }, 2943 ); 2944 2945 // AJAX add-to-cart button â intercept before the original handler 2946 $(document).on( 2947 "click", 2948 ".maimon-product-card .maimon_ajax_add_to_cart", 2949 function (e) { 2950 if ( 2951 $(this).closest( 2952 ".single_product_add_to_cart, .maimon-cart-drawer, #side-cart-drawer", 2953 ).length 2954 ) 2955 return; 2956 e.preventDefault(); 2957 e.stopImmediatePropagation(); // Prevent original theme handler 2958 2959 var $btn = $(this); 2960 var $card = $btn.closest(".maimon-product-card"); 2961 2962 if ($btn.prop("disabled") || $btn.hasClass("loading")) return; 2963 2964 var productId = $btn.data("product_id"); 2965 var $qtyInput = $btn 2966 .closest(".maimon-product-card__actions") 2967 .find(".qty-input"); 2968 var quantity = parseInt($qtyInput.val(), 10) || 1; 2969 var nonce = 2970 $btn.data("nonce") || 2971 (typeof cjpg_ajax_obj !== "undefined" 2972 ? cjpg_ajax_obj.nonce || "" 2973 : ""); 2974 var ajaxUrl = 2975 typeof cjpg_ajax_obj !== "undefined" ? cjpg_ajax_obj.ajaxurl : ""; 2976 2977 if (!ajaxUrl || !productId) return; 2978 2979 $btn.addClass("loading").text("\u05DE\u05D5\u05E1\u05D9\u05E3..."); // "××ס××£..." 2980 2981 $.ajax({ 2982 url: ajaxUrl, 2983 type: "POST", 2984 data: { 2985 action: "maimon_ajax_add_to_cart", 2986 product_id: productId, 2987 quantity: quantity, 2988 nonce: nonce, 2989 }, 2990 success: function (res) { 2991 $btn.removeClass("loading"); 2992 var isSuccess = !!(res && (res.success || res.fragments)); 2993 var dataObj = res && res.data ? res.data : {}; 2994 var fragments = 2995 dataObj.fragments || (res ? res.fragments || {} : {}); 2996 var cartHash = 2997 dataObj.cart_hash || (res ? res.cart_hash || "" : ""); 2998 2999 if (isSuccess) { 3000 // Toggle ALL cards with this product to "in-cart" (incl. Slick clones) 3001 var pid = String(productId); 3002 var $allCards = $(
3003 '.maimon_ajax_add_to_cart[data-product_id="' + pid + '"]', 3004 ).closest(".maimon-product-card"); 3005 $allCards.addClass("maimon-product-card--in-cart"); 3006 $allCards 3007 .find(".maimon-product-card__actions .qty-input") 3008 .val(quantity); 3009 $allCards 3010 .find(".maimon_ajax_add_to_cart") 3011 .attr("data-quantity", quantity) 3012 .data("quantity", quantity) 3013 .removeClass("loading") 3014 .text(quantity); 3015 3016 if (typeof dataObj.count !== "undefined") { 3017 updateCartBadges(dataObj.count); 3018 } 3019 3020 // Trigger cart update events 3021 $(document.body).trigger("maimon_cart_updated", [ 3022 typeof dataObj.count !== "undefined" 3023 ? dataObj.count 3024 : undefined, 3025 ]); 3026 $(document).trigger("maimon_product_added_to_cart"); 3027 $(document.body).trigger("maimon_product_added_to_cart"); 3028 $(document).trigger("added_to_cart", [ 3029 fragments, 3030 cartHash, 3031 $btn, 3032 ]); 3033 $(document.body).trigger("added_to_cart", [ 3034 fragments, 3035 cartHash, 3036 $btn, 3037 ]); 3038 } else { 3039 $btn.text("\u05D4\u05D5\u05E1\u05E4\u05D4 \u05DC\u05E1\u05DC"); // "×××¡×¤× ×ס×" 3040 } 3041 }, 3042 error: function () { 3043 $btn 3044 .removeClass("loading") 3045 .text("\u05D4\u05D5\u05E1\u05E4\u05D4 \u05DC\u05E1\u05DC"); 3046 }, 3047 }); 3048 }, 3049 ); 3050 } 3051 3052 /* ââ Sync exact product qty in cart for +/- controls ââ */ 3053 function setProductQtyInCart($card, qty) { 3054 var $btn = $card.find(".maimon_ajax_add_to_cart"); 3055 var ajaxUrl = 3056 typeof cjpg_ajax_obj !== "undefined" && cjpg_ajax_obj.ajaxurl 3057 ? cjpg_ajax_obj.ajaxurl 3058 : document.body.getAttribute("data-ajax-url") || ""; 3059 if (!ajaxUrl) return; 3060 3061 $.ajax({ 3062 url: ajaxUrl, 3063 type: "POST", 3064 data: { 3065 action: "maimon_set_product_qty_in_cart", 3066 product_id: $btn.data("product_id"), 3067 quantity: Math.max(0, parseInt(qty, 10) || 0), 3068 nonce: 3069 $btn.data("nonce") || 3070 (typeof cjpg_ajax_obj !== "undefined" 3071 ? cjpg_ajax_obj.nonce || "" 3072 : ""), 3073 }, 3074 success: function (res) { 3075 if (res && res.success) { 3076 if (res.data && typeof res.data.count !== "undefined") { 3077 updateCartBadges(res.data.count); 3078 } 3079 $(document.body).trigger("maimon_cart_updated", [ 3080 res.data && typeof res.data.count !== "undefined" 3081 ? res.data.count 3082 : undefined, 3083 ]); 3084 return; 3085 } 3086 3087 $(document.body).trigger("maimon_cart_updated"); 3088 if (res && res.data && res.data.message) { 3089 window.alert(res.data.message); 3090 } 3091 }, 3092 error: function () { 3093 $(document.body).trigger("maimon_cart_updated"); 3094 }, 3095 }); 3096 } 3097 3098 /* ââ Sync data-quantity on the add-to-cart button ââ */ 3099 function syncCartBtnQty($btn) { 3100 var $actions = $btn.closest(".maimon-product-card__actions"); 3101 var $cart = $actions.find(".maimon_ajax_add_to_cart"); 3102 var $input = $actions.find(".qty-input"); 3103 if ($cart.length && $input.length) { 3104 $cart 3105 .data("quantity", $input.val()) 3106 .attr("data-quantity", $input.val()); 3107 } 3108 } 3109 3110 return { init: init }; 3111 })(); 3112 3113 /* ========================================================== 3114 TASK 11 â "You May Also Like" Carousel Custom Arrows 3115 ========================================================== */ 3116 var carouselArrows = (function () { 3117 function init() { 3118 // If custom prev/next buttons exist alongside a Slick carousel, 3119 // wire them up. The inline <script> in the PHP template already 3120 // handles its own arrows (.maimon-yml-prev / .maimon-yml-next). 3121 // This handler covers any additional generic arrow pair. 3122 $(document).on("click", ".maimon-carousel-prev", function () { 3123 var $carousel = $(this) 3124 .closest(".maimon-you-may-like__wrapper") 3125 .find(".slick-initialized"); 3126 if ($carousel.length) { 3127 $carousel.slick("slickPrev"); 3128 } 3129 }); 3130 3131 $(document).on("click", ".maimon-carousel-next", function () { 3132 var $carousel = $(this) 3133 .closest(".maimon-you-may-like__wrapper") 3134 .find(".slick-initialized"); 3135 if ($carousel.length) { 3136 $carousel.slick("slickNext"); 3137 } 3138 }); 3139 3140 // Also handle the case where the carousel sits inside a 3141 // different wrapper (e.g. `.maimon_products_may_like_inner_carousel_list`) 3142 $(document).on( 3143 "click", 3144 ".maimon_products_may_like_inner_carousel_list .maimon-carousel-prev", 3145 function () { 3146 var $slider = $(this).siblings(".slick-initialized"); 3147 if (!$slider.length) { 3148 $slider = $(this) 3149 .closest(".maimon_products_may_like_inner_carousel_list") 3150 .find(".slick-initialized"); 3151 } 3152 if ($slider.length) { 3153 $slider.slick("slickPrev"); 3154 } 3155 }, 3156 ); 3157 3158 $(document).on( 3159 "click", 3160 ".maimon_products_may_like_inner_carousel_list .maimon-carousel-next", 3161 function () { 3162 var $slider = $(this).siblings(".slick-initialized"); 3163 if (!$slider.length) { 3164 $slider = $(this) 3165 .closest(".maimon_products_may_like_inner_carousel_list") 3166 .find(".slick-initialized"); 3167 } 3168 if ($slider.length) { 3169 $slider.slick("slickNext"); 3170 } 3171 }, 3172 ); 3173 } 3174 3175 return { init: init }; 3176 })(); 3177 3178 /* ========================================================== 3179 DOM READY â Initialize all modules 3180 ========================================================== */ 3181 $(document).ready(function () { 3182 brandsMega.init(); 3183 megaDropdown.init();
3184 miniCartBadge.init(); 3185 cartDrawer.init(); 3186 if (!window.maimonArchiveFilterV2Active) { 3187 productsFilter.init(); 3188 } 3189 productCardActions.init(); 3190 carouselArrows.init(); 3191 }); 3192})(jQuery); 3193 3194/* âââ Single Product Qty Buttons (Task 9) âââ */ 3195(function ($) { 3196 "use strict"; 3197 window.maimonSingleProductCartBound = true; 3198 $(document).ready(function () { 3199 $(document).on( 3200 "click", 3201 ".single_product_add_to_cart .single-product-add-btn", 3202 function (e) { 3203 e.preventDefault(); 3204 e.stopImmediatePropagation(); 3205 var $btn = $(this); 3206 var $row = $btn.closest(".single-product-cart-row"); 3207 if ($btn.hasClass("loading")) return; 3208 var productId = $btn.data("product_id"); 3209 var nonce = 3210 $row.data("nonce") || 3211 (typeof cjpg_ajax_obj !== "undefined" 3212 ? cjpg_ajax_obj.nonce || "" 3213 : "") || 3214 (typeof miniCartData !== "undefined" ? miniCartData.nonce : ""); 3215 var ajaxUrl = 3216 typeof cjpg_ajax_obj !== "undefined" && cjpg_ajax_obj.ajaxurl 3217 ? cjpg_ajax_obj.ajaxurl 3218 : ""; 3219 if (!ajaxUrl || !productId) return; 3220 $btn.addClass("loading").text("××ס××£..."); 3221 $.ajax({ 3222 url: ajaxUrl, 3223 type: "POST", 3224 data: { 3225 action: "maimon_ajax_add_to_cart", 3226 product_id: productId, 3227 quantity: 1, 3228 nonce: nonce, 3229 }, 3230 success: function (res) { 3231 $btn.removeClass("loading").text("×××¡×¤× ×ס×"); 3232 var fragments = 3233 res && res.data && res.data.fragments 3234 ? res.data.fragments 3235 : res && res.fragments 3236 ? res.fragments 3237 : {}; 3238 var cartHash = 3239 res && res.data && res.data.cart_hash 3240 ? res.data.cart_hash 3241 : res && res.cart_hash 3242 ? res.cart_hash 3243 : ""; 3244 if (res && (res.success || res.fragments)) { 3245 $row 3246 .addClass("single-product-cart-row--in-cart") 3247 .attr("data-in-cart", "1"); 3248 $row.find(".single-product-qty-val").text(1); 3249 if (res.data && typeof res.data.count !== "undefined") { 3250 window.maimonUpdateCartBadges(res.data.count); 3251 } 3252 $(document.body).trigger("maimon_cart_updated", [ 3253 res.data && typeof res.data.count !== "undefined" 3254 ? res.data.count 3255 : undefined, 3256 ]); 3257 $(document).trigger("maimon_product_added_to_cart"); 3258 $(document.body).trigger("maimon_product_added_to_cart"); 3259 $(document.body).trigger("added_to_cart", [ 3260 fragments, 3261 cartHash, 3262 $btn, 3263 ]); 3264 } 3265 }, 3266 error: function () { 3267 $btn.removeClass("loading").text("×××¡×¤× ×ס×"); 3268 }, 3269 complete: function () { 3270 if ($.active <= 1) { 3271 $("body").removeClass("maimon-cursor-spinner-active"); 3272 } 3273 }, 3274 }); 3275 }, 3276 ); 3277 3278 $(document).on( 3279 "click", 3280 '.single_product_add_to_cart .single-product-qty-btn[data-action="plus"]', 3281 function (e) { 3282 e.preventDefault(); 3283 var $row = $(this).closest(".single-product-cart-row"); 3284 var $val = $row.find(".single-product-qty-val"); 3285 var max = parseInt($row.data("max"), 10) || 999; 3286 var val = parseInt($val.text(), 10) || 1; 3287 var newVal = Math.min(val + 1, max); 3288 if (newVal === val) return; 3289 $val.text(newVal); 3290 singleProductSetQty($row, newVal); 3291 }, 3292 ); 3293 3294 $(document).on( 3295 "click", 3296 '.single_product_add_to_cart .single-product-qty-btn[data-action="minus"]', 3297 function (e) { 3298 e.preventDefault(); 3299 var $row = $(this).closest(".single-product-cart-row"); 3300 var $val = $row.find(".single-product-qty-val"); 3301 var val = parseInt($val.text(), 10) || 1; 3302 var newVal = Math.max(0, val - 1); 3303 $val.text(newVal); 3304 if (newVal === 0) { 3305 $row 3306 .removeClass("single-product-cart-row--in-cart") 3307 .attr("data-in-cart", "0"); 3308 } 3309 singleProductSetQty($row, newVal); 3310 }, 3311 ); 3312 3313 function singleProductSetQty($row, qty) { 3314 var productId = parseInt($row.data("product-id"), 10) || 0; 3315 var nonce = 3316 $row.data("nonce") || 3317 (typeof cjpg_ajax_obj !== "undefined" 3318 ? cjpg_ajax_obj.nonce || "" 3319 : "") || 3320 (typeof miniCartData !== "undefined" ? miniCartData.nonce : ""); 3321 var ajaxUrl = 3322 typeof cjpg_ajax_obj !== "undefined" && cjpg_ajax_obj.ajaxurl 3323 ? cjpg_ajax_obj.ajaxurl 3324 : ""; 3325 if (!ajaxUrl || !productId) return; 3326 $.post(ajaxUrl, { 3327 action: "maimon_set_product_qty_in_cart", 3328 product_id: productId, 3329 quantity: Math.max(0, parseInt(qty, 10) || 0), 3330 nonce: nonce, 3331 }).done(function (res) { 3332 if (res && res.success) { 3333 if (res.data && typeof res.data.count !== "undefined") { 3334 window.maimonUpdateCartBadges(res.data.count); 3335 } 3336 if (res.data && res.data.product_qty === 0) { 3337 $row 3338 .removeClass("single-product-cart-row--in-cart") 3339 .attr("data-in-cart", "0"); 3340 $row.find(".single-product-qty-val").text(1); 3341 } 3342 $(document.body).trigger("maimon_cart_updated", [ 3343 res.data && typeof res.data.count !== "undefined" 3344 ? res.data.count 3345 : undefined, 3346 ]); 3347 } 3348 }); 3349 } 3350 }); 3351})(jQuery);
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.