1/** 2 * @copyright (c) 2018, Bohemiasoft s.r.o. 25.04.2018 3 */ 4;var BS = BS || {}; 5(function(exports, global, settings) { 6 'use strict'; 7 8 var obj = { 9 10 /** 11 * Vracà true pokud je zadaný parametr ÄÃslo a zároveÅ nenà NaN 12 * @param num 13 * @returns {boolean} 14 */ 15 isNumber: function(num) { 16 return typeof num === "number" && !isNaN(num); 17 }, 18 19 /** 20 * Vracà true pokud je pÅedaná hodnota celé ÄÃslo 21 * @param val 22 */ 23 isInteger: function(val) { 24 //pokud můžeme, použijeme objekt Number 25 if(global.Number && global.Number.isInteger) { 26 return global.Number.isInteger(val); 27 } else { 28 return this.isNumber(val) 29 && global.isFinite(val) 30 && val % 1 === 0; 31 } 32 }, 33 34 /** 35 * Vracà true pokud má ÄÃslo nÄjaký exponent (desetinná mÃsta) 36 * @param val 37 * @returns {*|boolean} 38 */ 39 isFloat: function(val) { 40 return this.isNumber(val) 41 && global.isFinite(val) 42 && val % 1 !== 0; 43 }, 44 45 /** 46 * Vracà pÅesnost (poÄet desetinných mÃst). 47 * Vracà 0 pokud se jedná o celé ÄÃslo nebo pÅedaný argument nenà ÄÃslo 48 * @param num 49 * @returns {number} 50 */ 51 precision: function(num) { 52 var p = 0, e = 1; 53 if(this.isNumber(num) 54 && global.isFinite(num)) { 55 while(this.round(num * e) / e !== num) { 56 p++; 57 e = Math.pow(10, p); 58 } 59 } 60 return p; 61 }, 62 63 /** 64 * Zaokrouhlenà ÄÃsla 65 * @param num 66 * @param p 67 * @returns (number) 68 */ 69 round: function(num, p) { 70 var v; 71 p = p || 0; 72 if(!this.isNumber(num) || !this.isInteger(p)) { 73 v = 0; 74 } else { 75 var f = Math.pow(10, p); 76 v = Math.round(num * f) / f; 77 } 78 return v; 79 }, 80 81 /** 82 * Parsovánà stringu na ÄÃslo 83 * @param string 84 * @returns (number) 85 */ 86 parse: function(string) { 87 var v = string; 88 if(settings.decPoint !== ".") { 89 //poslednà výskyt - napÅ. 12(,)(54) 90 var patt = "(%s%)([^%s%]+)$"; 91 patt = patt.replace(new RegExp("%s%", "g"), settings.decPoint); 92 v = v.replace(new RegExp(patt), function() { 93 return "." + arguments[2]; 94 }); 95 } 96 return parseFloat(v); 97 }, 98 99 /** 100 * Jednoduché formátovánà ÄÃsla na výstup (string) 101 * @param num 102 * @param p 103 * @returns {string} 104 */ 105 format: function(num, p) { 106 var f; 107 p = p || 0; 108 num = this.round(num, p); 109 f = num.toFixed(p); 110 if(p > 0) { 111 f = f.replace(".", settings.decPoint); 112 } 113 return f; 114 }, 115 116 /** 117 * Vrátà nastavenà objektu 118 * Pokud je param prop zadán, vrátà konkrétnà nastavenÃ, jinak celý objekt 119 * @param prop 120 * @returns {*} 121 */ 122 getSettings: function(prop) { 123 if(prop) { 124 return settings[prop]; 125 } else { 126 return Object.assign({}, settings); 127 } 128 } 129 }; 130 131 if(!exports.Number) { 132 exports.Number = obj; 133 } 134})(BS, window, BS.env); 135 136(function(BS, $, undefined) { 137 'use strict'; 138 139 function init_tooltips() { 140 $("[data-tip]").each(function() { 141 var options = {}; 142 if(this.dataset.tipOptions) { 143 try { 144 options = JSON.parse(this.dataset.tipOptions); 145 } catch(err) { 146 console.error("Tip options wrong format!"); 147 } 148 } 149 var tipSettings = { 150 classes: ["app-tooltip"], 151 showArrow: true, 152 offsetY: 0, 153 offsetX: 0 154 }; 155 if(options.class) { 156 var c = options.class.split(/\s+/); 157 tipSettings.classes = tipSettings.classes.concat(c); 158 } 159 if(options.showArrow !== undefined) { 160 tipSettings.showArrow = !!options.showArrow; 161 //TODO pÅeÄist z nastavenà 162 tipSettings.offsetY = tipSettings.showArrow ? 0 : -10; 163 } 164 $(this).qtip({ 165 content: { 166 text: $("#" + this.dataset.tipContent) 167 }, 168 position: { 169 at: "top center", 170 my: "bottom center", 171 viewport: ($(window)), 172 adjust: { 173 y: tipSettings.offsetY, 174 x: tipSettings.offsetX 175 } 176 }, 177 show: { 178 event: "mouseenter", 179 solo: false 180 }, 181 hide: { 182 event: "mouseleave", 183 delay: 100 184 }, 185 style: { 186 classes: tipSettings.classes.join(" "), 187 tip: tipSettings.showArrow 188 } 189 }); 190 }); 191 } 192 193 if(!BS.ui) BS.ui = {}; 194 BS.ui.tooltip = { 195 init: function() { 196 init_tooltips(); 197 } 198 } 199})(BS, jQuery); 200 201(function(BS, closeBtn, notification) { 202
203 function removeNotification(btn) { 204 var parent = btn.parentElement, 205 found = false; 206 while(!found && parent) { 207 if(parent.classList.contains(notification)) { 208 found = true; 209 } 210 } 211 parent.parentNode.removeChild(parent); 212 } 213 214 if(!BS.ui) BS.ui = {}; 215 BS.ui.notifications = { 216 init: function() { 217 document.body.addEventListener("click", function(e) { 218 var el = e.target; 219 if(el.classList.contains(closeBtn)) { 220 removeNotification(el); 221 } 222 }); 223 } 224 } 225})(BS, "notification-close", "notification"); 226 227(function(BS, WA, $) { 228 'use strict'; 229 230 function init(form) { 231 form.validate({ 232 rules: { 233 subscribe_name: { 234 required: true 235 }, 236 subscribe_email: { 237 required: true, 238 email: true 239 }, 240 subscribe_accept: { 241 required: true 242 } 243 }, 244 messages: { 245 subscribe_name: { 246 required: WA.Translation._error_empty_field 247 }, 248 subscribe_email: { 249 required: WA.Translation._error_empty_field, 250 email: WA.Translation._error_invalid_mail 251 } 252 }, 253 highlight: function(el) { 254 $(el).closest(".form-group").addClass("has-error"); 255 }, 256 unhighlight: function(el) { 257 $(el).closest(".form-group").removeClass("has-error"); 258 }, 259 errorPlacement: function(error, el) { 260 if (el.attr("name") !== "subscribe_accept") { 261 error.insertAfter(el); 262 } 263 } 264 }); 265 } 266 267 if(!BS.GDPR) BS.GDPR = {}; 268 BS.GDPR.subscribeForm = { 269 init: function(form) { 270 var actualForm = $(form).find("form"); 271 init(actualForm); 272 } 273 }; 274 275})(BS, WA, jQuery); 276 277(function(BS, WA, $) { 278 'use strict'; 279 280 function initForm(form) { 281 form.find("input[name='newsletter_mail']").on("focus", function() { 282 //naÄteme a zobrazÃme captchu 283 var cField = form.find(".captcha-input").children("input").get(0); 284 //v pÅÃpadÄ reCaptcha volby polÃÄko neexistuje... 285 if(cField) { 286 if(BS.captcha 287 && $.isFunction(BS.captcha[cField.name])) { 288 //reload obrázku 289 BS.captcha[cField.name](); 290 } 291 } 292 form.find(".captcha-box").removeClass("hidden"); 293 }); 294 form.validate({ 295 rules: { 296 newsletter_mail: { 297 required: true, 298 email: true 299 }, 300 gdpr_accept: { 301 required: true 302 } 303 }, 304 messages: { 305 newsletter_mail: { 306 required: WA.Translation._error_empty_field, 307 email: WA.Translation._error_invalid_mail 308 } 309 }, 310 highlight: function(el) { 311 if(el.name === "newsletter_mail") { 312 $(el).parent().addClass("has-error"); 313 } 314 }, 315 unhighlight: function(el) { 316 if(el.name === "newsletter_mail") { 317 $(el).parent().removeClass("has-error"); 318 } 319 }, 320 errorPlacement: function(error, el) { 321 if (el.attr("name") !== "gdpr_accept") { 322 error.insertAfter(el); 323 } 324 } 325 }); 326 } 327 328 if(!BS.GDPR) BS.GDPR = {}; 329 BS.GDPR.newsletterForm = { 330 init: function(selector) { 331 $(selector).each(function() { 332 initForm($(this).closest("form")); 333 }); 334 } 335 } 336 337})(BS, WA, jQuery); 338 339(function(window, document, exports, undefined) { 340 'use strict'; 341 342 var PopMessage = function(options) { 343 options = options || {}; 344 var self = this, 345 timer = parseInt(options.timer); 346 this._options = options; 347 this.create(options); 348 if(!isNaN(timer) 349 && timer > 0) { 350 self.timeout = setTimeout(function() { 351 self.hide(); 352 }, timer); 353 } 354 }; 355 356 PopMessage.prototype = { 357 358 create: function(options) { 359 var self = this; 360 var wrapper = this.createElement(PopMessage.template.el); 361 362 //interaktivita 363 var controls = wrapper.querySelector(".pop-controls"); 364 if(controls) { 365 if(options.interactive === true) { 366 var closeBtn = wrapper.querySelector(".pop-close"); 367 if(closeBtn) { 368 closeBtn.addEventListener("click", function(e) { 369 self.hide(); 370 }); 371 } 372 } else { 373 controls.remove(); 374 } 375 } 376 377 //ikona 378 var icon = wrapper.querySelector(".pop-icon"); 379 if(icon) { 380 if(this.isStringSet(options.icon)) { 381 this.addClass(icon.children[0], options.icon); 382 this.addClass(wrapper, "w-icon"); 383 } else { 384 icon.remove(); 385 } 386 } 387 388 //typ 389 if(this.isStringSet(options.type)) { 390 this.addClass(wrapper, options.type); 391 } 392 393 //titulek 394 var title = wrapper.querySelector(".pop-title"); 395 if(title) { 396 if(this.isStringSet(options.title)) { 397 this.setText(title, options.title); 398 } else { 399 title.remove(); 400 } 401 } 402 403 //zprava 404 var content = wrapper.querySelector(".pop-content"); 405 if(content) { 406 if(this.isStringSet(options.message)) 407 { 408 this.setText(content, options.message); 409 } 410 } 411 412 this.el = wrapper; 413 }, 414 415 hide: function() {
416 //odstranÄnà z domu 417 if(this.timeout) { 418 clearTimeout(this.timeout); 419 this.timeout = null; 420 } 421 this.el.remove(); 422 this.callFunc("onHide", this.el); 423 }, 424 425 show: function() { 426 document.body.append(this.el); 427 this.callFunc("onShow", this.el); 428 }, 429 430 createElement: function(elHtml) { 431 var t = document.createElement("div"); 432 t.innerHTML = elHtml.trim(); 433 434 return t.firstChild; 435 }, 436 437 addClass: function(el, classList) { 438 var classes = classList.split(/\s+/), 439 i = 0; 440 //IE má pouze základnà podporu pro classList.add() 441 //tÅÃdy musÃme vložit postupnÄ 442 for(; i < classes.length; i++) { 443 el.classList.add(classes[i]); 444 } 445 }, 446 447 isString: function(v) { 448 return typeof v === "string"; 449 }, 450 451 isStringSet: function(v) { 452 return this.isString(v) && v !== ""; 453 }, 454 455 callFunc: function(c) { 456 if(this.isCallbackSet(c)) { 457 this._options.callbacks[c].apply(this, Array.prototype.slice.call(arguments, 1)); 458 } 459 }, 460 461 isCallbackSet: function(c) { 462 if(typeof this._options.callbacks === "object" && this._options.callbacks !== null) { 463 return typeof this._options.callbacks[c] === "function"; 464 } else { 465 return false; 466 } 467 }, 468 469 setText: function(el, text) { 470 el.innerText = text.trim(); 471 } 472 }; 473 474 PopMessage.template = { 475 el: '<div class="pop-message"><div class="pop-container"><div class="pop-controls"><span class="pop-close"><i>×</i></span></div><div class="pop-icon"><i></i></div><h5 class="pop-title"></h5><p class="pop-content"></p></div></div>' 476 }; 477 478 exports.PopMessage = PopMessage; 479 480})(window, document, BS.ui); 481 482(function(ui, texts, design) { 483 'use strict'; 484 485 //pouze jedna instance 486 var pop = null; 487 488 ui.popMessage = { 489 show: function(options) { 490 console.log(options); 491 this.hide(); 492 pop = new ui.PopMessage(options); 493 pop.show(); 494 }, 495 496 hide: function() { 497 if(pop) { 498 pop.hide(); 499 pop = null; 500 } 501 }, 502 503 alert: function(message, showIcon, options = {}) { 504 showIcon = typeof showIcon !== "undefined" ? !!showIcon : true; 505 //Å¡ablony mohou použÃvat různé sady ikon 506 var iconClass = design.isLayout3 ? "fa fa-exclamation" : "icon-exclamation-sign"; 507 options = Object.assign({ 508 type: "alert", 509 title: texts._error, 510 message: message, 511 timer: 5000, //5s 512 icon: showIcon ? iconClass : "", 513 interactive: true, 514 callbacks: { 515 onHide: function() { 516 pop = null; 517 } 518 } 519 }, options); 520 this.show(options); 521 }, 522 success: function(message, showIcon, options = {}) { 523 showIcon = typeof showIcon !== "undefined" ? !!showIcon : true; 524 //Å¡ablony mohou použÃvat různé sady ikon 525 var iconClass = design.isLayout3 ? "fa fa-check" : "icon-check"; 526 options = Object.assign({ 527 type: "success", 528 title: texts._success, 529 message: message, 530 timer: 5000, //5s 531 icon: showIcon ? iconClass : "", 532 interactive: true, 533 callbacks: { 534 onHide: function() { 535 pop = null; 536 } 537 } 538 }, options); 539 this.show(options); 540 }, 541 warning: function(message, showIcon, options = {}) { 542 showIcon = typeof showIcon !== "undefined" ? !!showIcon : true; 543 //Å¡ablony mohou použÃvat různé sady ikon 544 var iconClass = design.isLayout3 ? "fa fa-question" : "icon-exclamation-sign"; 545 options = Object.assign({ 546 type: "warning", 547 title: texts._warning, 548 message: message, 549 timer: 5000, //5s 550 icon: showIcon ? iconClass : "", 551 interactive: true, 552 callbacks: { 553 onHide: function() { 554 pop = null; 555 } 556 } 557 }, options); 558 this.show(options); 559 } 560 561 }; 562})(BS.ui, WA.Translation, BS.Design); 563 564(function (document, BS, exports, undefined) { 565 'use strict'; 566 567 var spinActions = { 568 INC: 1, 569 DEC: 2 570 }; 571 var evPluginName = "InputSpinner"; 572 573 function InputSpinner(el, options) { 574 this.wrapper = el; 575 this.input = el.querySelector(".spin-input"); 576 this.product_info = {}; 577 if(this.input.dataset.productInfo) { 578 this.product_info = JSON.parse(this.input.dataset.productInfo); 579 } 580 this.widgets = { 581 inc: el.querySelector(".spin-inc"),
582 dec: el.querySelector(".spin-dec") 583 }; 584 this.state = ""; 585 this.vars = { 586 spins: 1, 587 timeout: null 588 }; 589 this.settings = this.extendSettings(InputSpinner.defaults, options); 590 //inicializace 591 this.registerEvents(); 592 } 593 594 InputSpinner.prototype = { 595 extendSettings: function(obj1, obj2) { 596 var obj = {}, 597 key; 598 for(key in obj1) { 599 if(obj1.hasOwnProperty(key)) { 600 if(!obj2.hasOwnProperty(key)) { 601 obj[key] = obj1[key]; 602 } else { 603 obj[key] = obj2[key]; 604 } 605 } 606 } 607 return obj; 608 }, 609 /** 610 * Registarce událostà 611 */ 612 registerEvents: function() { 613 var self = this; 614 if(this.widgets.inc) { 615 this.widgets.inc.addEventListener("mousedown", function(e) { 616 self.startSpin(spinActions.INC); 617 }); 618 } 619 if(this.widgets.dec) { 620 this.widgets.dec.addEventListener("mousedown", function(e) { 621 self.startSpin(spinActions.DEC); 622 }); 623 } 624 if(this.widgets.inc 625 || this.widgets.dec) { 626 //mouseup na document, jelikož po stisknutà myÅ¡Ãtka a posunutà kurzoru je event vyvolán pro jiný element! 627 document.addEventListener("mouseup", function(e) { 628 if(self.isSpinning()) { 629 self.stopSpin(); 630 } 631 }); 632 } 633 if(this.input) { 634 this.input.addEventListener("change", function(e) { 635 if((e instanceof CustomEvent || e.detail !== undefined) && e.detail.plugin === evPluginName) return; 636 var v = self.getValue(), 637 newV; 638 if(v < self.settings.min) { 639 newV = self.settings.min; 640 } else if(v > self.settings.max) { 641 newV = self.settings.max; 642 } else { 643 newV = v; 644 } 645 if(newV !== undefined) { 646 self.setValue(newV); 647 } 648 }); 649 } 650 }, 651 /** 652 * PÅiÄtenà hodnoty, dalšà volánà funkcà setTimeout 653 * @param dir int 654 */ 655 startSpin: function(dir) { 656 var d; 657 if(this.vars.spins === 1) { 658 //prvnà kolo 659 if(dir === spinActions.INC) { 660 this.increment(); 661 } else if(dir === spinActions.DEC) { 662 this.decrement(); 663 } 664 d = 1; 665 } else if(this.vars.spins < 3) { 666 d = 1.5; 667 } else if(this.vars.spins < 8) { 668 d = 2.5; 669 } else { 670 d = 4; 671 } 672 673 var self = this; 674 this.vars.timeout = setTimeout(function() { 675 self.timeoutFn(dir); 676 }, Math.ceil(this.settings.speed / d)); 677 this.vars.spins++; 678 }, 679 /** 680 * Zastavenà pÅiÄÃtánà 681 */ 682 stopSpin: function() { 683 window.clearTimeout(this.vars.timeout); 684 this.vars.spins = 1; 685 this.vars.timeout = null; 686 this.triggerEvent(this.input, "change", this.getEventData()); 687 }, 688 /** 689 * Funkce pro pÅiÄtenÃ/odeÄtenà hodnoty. 690 * ZároveÅ volá dalšà kolo 691 * @param dir int 692 */ 693 timeoutFn: function(dir) { 694 if(dir === spinActions.INC) { 695 this.increment(); 696 } else if(dir === spinActions.DEC) { 697 this.decrement(); 698 } 699 this.startSpin(dir); 700 }, 701 /** 702 * Zvýšenà hodnoty o nastavený krok 703 */ 704 increment: function() { 705 var val = this.getValue(), 706 p = BS.Number.precision(val); 707 if(val !== false) { 708 if(val < this.settings.maxSpin) { 709 var pw = Math.pow(10, p); 710 val = Math.round(val * pw + this.settings.step * pw) / pw; 711 if(val > this.settings.maxSpin) { 712 val = this.settings.maxSpin; 713 } 714 this.state = "+"; 715 this.setValue(val); 716 } 717 } 718 }, 719 /** 720 * SnÞenà hodnoty o nastavený krok 721 */ 722 decrement: function() { 723 var val = this.getValue(), 724 p = BS.Number.precision(val); 725 if(val !== false) { 726 if(val > this.settings.minSpin) { 727 var pw = Math.pow(10, p); 728 val = Math.round(val * pw - this.settings.step * pw) / pw; 729 if(val < this.settings.minSpin) { 730 val = this.settings.minSpin; 731 } 732 this.state = "-"; 733 this.setValue(val); 734 } 735 } 736 }, 737 isSpinning: function() { 738 return this.vars.timeout !== null; 739 }, 740 /** 741 * Nastavenà hodnoty v polÃÄku 742 * @param val 743 * @param triggerEv 744 */ 745 setValue: function(val, triggerEv) { 746 var p = 0, 747 valP = BS.Number.precision(val); 748 if(this.settings.floatEnabled 749 && this.settings.precision > 0) { 750 p = valP > this.settings.precision ? this.settings.precision : valP; 751 } 752 if(this.input) { 753 this.input.value = BS.multiples.checkIncDec(BS.Number.format(val, p), this.product_info || null, this.state); 754 if(!!triggerEv) { 755 this.triggerEvent(this.input, "change", {}); 756 } 757 } 758 }, 759 /** 760 * Vyvolánà eventu 761 * @param el 762 * @param event 763 * @param params 764 */ 765 triggerEvent: function(el, event, params) { 766 var ev; 767 if(typeof window.CustomEvent === "function") { 768 //normálnà prohlÞeÄe 769 ev = new CustomEvent(event, {bubbles: true, detail: params}); 770 } else { 771 //IE 772 ev = document.createEvent("CustomEvent"); 773 ev.initCustomEvent(event, true, false, params); 774 } 775 el.dispatchEvent(ev); 776 }, 777 778 /** 779 * Vrácenà hodnoty z polÃÄka 780 * @returns {number|boolean} 781 */ 782 getValue: function() { 783 var value; 784 if(this.input) { 785 value = BS.Number.parse(this.input.value) || this.settings.defaultValue; 786 } else { 787 value = false;
788 } 789 790 return value; 791 }, 792 793 /** 794 * Vrátà object s custom event daty rozÅ¡ÃÅený o pÅedané parametry 795 * @param params 796 * @returns object 797 */ 798 getEventData: function(params) { 799 params = params || {}; 800 var p = {plugin: evPluginName}; 801 var keys = Object.keys(params); 802 for(var i = 0; i < keys.length; i++) { 803 if(keys[i] !== "plugin") { 804 p[keys[i]] = params[keys[i]]; 805 } 806 } 807 808 return p; 809 } 810 }; 811 812 InputSpinner.defaults = { 813 //krok 814 step: 1, 815 //minimálnà hodnota, která může být do polÃÄka vložena 816 min: 1, 817 //minimálnà hodnota, na kterou je možné se proklikat 818 minSpin: 1, 819 //maximálnà hodnota, na kterou je možné se proklikat 820 maxSpin: 9999, 821 //výchozà hodnota (napÅ. pokud nenà vloženo ÄÃslo) 822 defaultValue: 1, 823 //poÄet povolených deset. mÃst (pokud floatEnabled == true) 824 precision: 2, 825 //maximálnà hodnota, která může být do polÃÄka vložena 826 max: 9999, 827 //rychlost 828 speed: 500, 829 //povolenà deset. ÄÃsel 830 floatEnabled: false 831 }; 832 exports.InputSpinner = InputSpinner; 833})(document, BS, BS.ui); 834 835(function(plugin, env, ui) { 836 var pluginName = "__pluginInputSpinner"; 837 var options = { 838 floatEnabled: env.basketFloatEnabled, 839 min: env.basketFloatEnabled ? 0.01 : 1 840 }; 841 var initInputSpinners = function() { 842 $(plugin).each(function() { 843 if(!$.data(this, pluginName)) { 844 $.data(this, pluginName, new ui.InputSpinner(this, options)); 845 } 846 }); 847 }; 848 849 ui.inputSpinner = { 850 init: initInputSpinners 851 }; 852})("[data-input-spinner]", BS.env, BS.ui); 853 854(function(exports, document, undefined) { 855 "use strict"; 856 857 var _initialized = false; 858 var _map = {}; 859 var _selShipping = null; 860 var _form; 861 862 var _getServices = function(method) { 863 return _map[method] !== undefined ? _map[method] : null; 864 }; 865 866 var _runEvents = function(els, selected) { 867 if(!els) return; 868 869 for(var i = 0, node; i < els.length; i++) { 870 node = els[i]; 871 //vynutime odskrtnuti 872 if(node.check || !selected) { 873 node.el.checked = selected; 874 } 875 } 876 }; 877 878 var _mapServices = function() { 879 var svcs = document.querySelectorAll(".delivery-additional-svcs"), 880 inputs; 881 for(var i = 0, method; i < svcs.length; i++) { 882 method = svcs[i].dataset.deliveryMethod; 883 if(method !== undefined) { 884 inputs = svcs[i].querySelectorAll("input[data-additional-service]"); 885 if(inputs.length) { 886 _map[method] = { 887 els: [] 888 }; 889 for(var j = 0; j < inputs.length; j++) { 890 _map[method].els.push({ 891 el: inputs[j], 892 check: parseInt(inputs[j].dataset.additionalServiceCheck) === 1 893 }); 894 } 895 } 896 } 897 } 898 }; 899 900 var _registerFormEvents = function() { 901 _form.addEventListener("change", function(e) { 902 if(e.target.nodeName === "INPUT" 903 && e.target.name === "postovne_form") { 904 var svc; 905 //zruseni predchozich 906 if(_selShipping) { 907 svc = _getServices(_selShipping); 908 if(svc) { 909 _runEvents(svc.els, false); 910 } 911 } 912 913 svc = _getServices(e.target.value); 914 if(svc) { 915 _runEvents(svc.els, true); 916 } 917 918 _selShipping = e.target.value; 919 } 920 }); 921 }; 922 923 924 if(!exports.delivery) exports.delivery = {}; 925 exports.delivery.additionalServices = { 926 init: function(selector) { 927 _form = document.getElementById(selector); 928 if(!_initialized && _form !== null) { 929 _mapServices(); 930 _registerFormEvents(); 931 _initialized = true; 932 } else { 933 console.error("Already initialized"); 934 } 935 } 936 }; 937}).apply(this, [BS, document]); 938 939(function(exports, document) { 940 "use strict"; 941 942 class Tab { 943 constructor(container) { 944 this.container = container; 945 this.nav = container.querySelector(".nav-tabs"); 946 this.registerEvents(); 947 } 948 949 registerEvents() { 950 this.nav.addEventListener('click', e => { 951 var navLink = e.target.closest('.nav-link'); 952 if(navLink) { 953 e.preventDefault(); 954 this.show(navLink); 955 } 956 }); 957 } 958 959 show(navLink) { 960 var activePane = document.getElementById(navLink.getAttribute('href').substring(1)); 961 if(!activePane) { 962 throw new Error("Tab pane not found for " + navLink.getAttribute('href')); 963 } 964 965 this.updatePanes(activePane); 966 this.updateNav(navLink); 967 } 968 969 updatePanes(activePane) { 970 var tabs = this.container.querySelectorAll('.tab-pane'); 971 for(var i = 0; i < tabs.length; i++) { 972 var pane = tabs[i]; 973 if(pane === activePane) { 974 pane.classList.add('active'); 975 } else { 976 pane.classList.remove('active'); 977 } 978 } 979 } 980 981 updateNav(activeLink) { 982 var links = this.nav.querySelectorAll('.nav-link'); 983 for(var i = 0; i < links.length; i++) { 984 var link = links[i]; 985 if(link === activeLink) { 986 link.classList.add('active'); 987 } else { 988 link.classList.remove('active'); 989 } 990 } 991 } 992 } 993 994 exports.Tab = Tab; 995}).apply(this, [BS, document]); 996 997$(function() { 998 BS.ui.tooltip.init(); 999 BS.ui.notifications.init(); 1000 (function(form) { 1001 if(form) { 1002 BS.GDPR.subscribeForm.init(form); 1003 } 1004 })(document.getElementById("subscribeForm")); 1005 BS.GDPR.newsletterForm.init(".wrapper_newsletter"); 1006 1007 (function(carousel) { 1008 'use strict';
1009 var wrapper = $(carousel); 1010 if(wrapper.length) { 1011 wrapper.find(".owl-carousel").owlCarousel({ 1012 autoplay: true, 1013 autoplayTimeout: 5000, 1014 items: 3, 1015 loop: false, 1016 nav: true, 1017 dots: false, 1018 lazyLoad: true, 1019 autoWidth: false, 1020 autoplayHoverPause: true, 1021 rewind: true, 1022 margin: 10, 1023 navText: ["<i class='nav-icon'></i>","<i class='nav-icon'></i>"], 1024 navContainerClass: "nav-container", 1025 navClass: ["nav-prev", "nav-next"] 1026 }); 1027 } 1028 })("#categoriesCarousel"); 1029 1030 (function(productGallery) { 1031 'use strict'; 1032 var gallery = $(productGallery), carousel, settings; 1033 var defaults = { 1034 autoplay: false, 1035 autoplayTimeout: 5000, 1036 items: 1, 1037 loop: true, 1038 nav: true, 1039 rewind: false, 1040 dots: true, 1041 navText: ["<i class='nav-icon'></i>","<i class='nav-icon'></i>"], 1042 navContainerClass: "nav-container", 1043 navClass: ["nav-prev", "nav-next"] 1044 }; 1045 var fixed = { 1046 lazyLoad: true 1047 }; 1048 if(gallery.length) { 1049 carousel = gallery.find(".owl-carousel"); 1050 if(carousel.length) { 1051 settings = carousel.data("carousel") || {}; 1052 carousel 1053 .owlCarousel($.extend(true, {}, defaults, settings, fixed)); 1054 } 1055 } 1056 })("#productGallery"); 1057 1058 BS.ui.inputSpinner.init(); 1059 1060 (function(BS, formSelector) { 1061 'use strict'; 1062 1063 var reloadPage = function(page, delay) { 1064 setTimeout(function() { 1065 if(page 1066 && page !== "") 1067 { 1068 window.location.href = page; 1069 } 1070 else 1071 { 1072 window.location.reload(); 1073 } 1074 }, ( (Number.isInteger(delay)) ? delay : 0 )); 1075 }; 1076 1077 var form = $(formSelector).eq(0); 1078 var requestSend = false; 1079 if(form.length) { 1080 form.on("submit", function(e) { 1081 e.preventDefault(); 1082 if(!requestSend) { 1083 var request = BS.extend(BS.Request.$default, { 1084 data: { 1085 action: "Eshop_login", 1086 request: { 1087 action: "login", 1088 data: { 1089 login_data: { 1090 username: form.get(0).login.value, 1091 password: form.get(0).heslo.value 1092 }, 1093 info: { 1094 page: window.location.pathname, 1095 url: window.location.href 1096 } 1097 } 1098 }, 1099 id_zakaznik: BS.User.id 1100 }, 1101 success: function(data) { 1102 if(data.success) { 1103 form.find(".login-error").removeClass("show-msg"); 1104 form.find(".login-success").addClass("show-msg"); 1105 reloadPage(data.redirect ? data.redirect_to : null, 1000); 1106 } else { 1107 form.find(".login-error").addClass("show-msg"); 1108 requestSend = false; 1109 } 1110 } 1111 }); 1112 $.ajax(request); 1113 requestSend = true; 1114 } 1115 }); 1116 } 1117 })(BS, "form[data-form-login]"); 1118 1119 if(document.body.classList.contains("page-e-basket")) { 1120 BS.delivery.additionalServices.init("basket_form"); 1121 } 1122 1123 // select2 , pro krypton a kryptonit jiná Å¡ÃÅka, pro staré Å¡ablony nezobrazovat 1124 if(BS.Design.template.name !== undefined && BS.Design.isLayout3 && !BS.Design.template.name.match(/krypton/) ) { 1125 $('.public-select2-styled').select2({ 1126 width:"95%" 1127 }).maximizeSelect2Height(); 1128 } 1129 else if (BS.Design.template.name !== undefined && BS.Design.template.name.match(/krypton/)) 1130 { 1131 $('.public-select2-styled').select2().maximizeSelect2Height(); 1132 } 1133 1134 $('body').on('click', '.hc-gdpr-min' ,function () { 1135 $('.hc-gdpr-long').toggle(); 1136 }); 1137 1138 // zobrazà loadÃtko pÅi kliku na objednat v koÅ¡Ãku pokud zákaznÃk nahrál nÄjaký obrázek 1139 $('body.page-e-basket').on('submit', function(){ 1140 1141 if($('.leave-note .product-upload-img').length > 0 ) { 1142 var files = $('input[type="file"]'); 1143 $.each(files, function (key, item) { 1144 if (item.files[0] !== undefined) { 1145 BS.Fce.showLoadingOverlay(WA.Translation._uploading , WA.Translation._take_time); 1146 return false;
1147 } 1148 }); 1149 } 1150 }); 1151 1152 (function() { 1153 "use strict"; 1154 1155 const map = new WeakMap(); 1156 1157 class PricePreview { 1158 constructor(element) { 1159 this.element = element; 1160 this.clone = element.cloneNode(true); 1161 } 1162 1163 update(html) { 1164 this.element.innerHTML = html; 1165 } 1166 1167 default() { 1168 var clone = this.clone.cloneNode(true); 1169 this.element.replaceWith(clone); 1170 this.element = clone; 1171 } 1172 }; 1173 1174 class QuantityDiscount { 1175 constructor(container, options) { 1176 this.container = container; 1177 this.options = options; 1178 this.level = null; 1179 this.init(); 1180 } 1181 1182 init() { 1183 var container = this.container, 1184 input = container.querySelector('.quantity-input'), 1185 priceSelector, 1186 priceVatSelector, 1187 that = this, 1188 priceEl, 1189 priceElVat; 1190 1191 if(!input) { 1192 return; 1193 } 1194 1195 if(container.classList.contains('detail-info')) { 1196 priceVatSelector = '.price-vat > .price-value'; 1197 priceSelector = '.price-novat'; 1198 } else if(container.classList.contains('product3')) { 1199 priceVatSelector = '.product3Price'; 1200 } else if(container.classList.contains('product')) { 1201 priceVatSelector = '.productPrice'; 1202 } else { 1203 throw new Error("Unknown container type"); 1204 } 1205 1206 priceElVat = container.querySelector(priceVatSelector); 1207 if(!priceElVat) { 1208 console.log("No price element found"); 1209 return; 1210 } 1211 1212 this.priceVatPreview = new PricePreview(priceElVat); 1213 priceEl = container.querySelector(priceSelector); 1214 this.pricePreview = priceEl ? new PricePreview(priceEl) : null; 1215 1216 $(input).on("change", function() { 1217 that.update(); 1218 }); 1219 this.input = input; 1220 } 1221 1222 getLevel(value) { 1223 var val = parseFloat(value); 1224 var level; 1225 1226 level = this.options.levels.findIndex(function(level) { 1227 return val >= level.quantity; 1228 }); 1229 1230 return level !== -1 ? this.options.levels[level] : null; 1231 } 1232 1233 update() { 1234 var level = this.getLevel(this.input.value); 1235 if(level) { 1236 if(level !== this.level) { 1237 this.priceVatPreview.update(level.price_vat_html); 1238 if(this.pricePreview && level.price_html) { 1239 this.pricePreview.update(level.price_html); 1240 } 1241 } 1242 } else if(this.level) { 1243 this.priceVatPreview.default(); 1244 if(this.pricePreview) { 1245 this.pricePreview.default(); 1246 } 1247 } 1248 1249 BS.event.trigger('quantity-discount:update', { level }); 1250 1251 this.level = level; 1252 } 1253 } 1254 1255 var initWidgets = function() { 1256 var containers = document.querySelectorAll('[data-quantity-discount]'); 1257 for(var i = 0; i < containers.length; i++) { 1258 var instance, 1259 container = containers[i]; 1260 if(!map.has(container)) { 1261 try { 1262 instance = new QuantityDiscount(container, { 1263 levels: JSON.parse(container.dataset.quantityDiscount), 1264 }); 1265 map.set(container, instance); 1266 } catch(err) { 1267 console.error(err); 1268 } 1269 } 1270 } 1271 }; 1272 1273 initWidgets(); 1274 $(document).on('page:productsLoaded', function() { 1275 initWidgets(); 1276 }); 1277 })(); 1278 1279 (function() { 1280 "use strict"; 1281 1282 var container = document.querySelector('[data-unit-prices]'); 1283 if(!container) return; 1284 var priceLabels = container.querySelectorAll('[data-unit-price-label]'); 1285 try { 1286 var levels = JSON.parse(container.dataset.unitPrices); 1287 } catch(err) { 1288 console.error("Error initializing unit prices:", err); 1289 return; 1290 } 1291 1292 var findPricelevel = function(level) { 1293 var quantity = level ? level.quantity : null; 1294 1295 return levels.find(function(l) { 1296 return l.quantity === quantity; 1297 }); 1298 } 1299 1300 var replacePrices = function(level) { 1301 var priceLevel = findPricelevel(level); 1302 for(var i = 0; i < priceLabels.length; i++) {
1303 var index = priceLabels[i].dataset.unitPriceLabel; 1304 var key = 'label' + index; 1305 if(priceLevel.hasOwnProperty(key)) { 1306 priceLabels[i].innerHTML = priceLevel[key]; 1307 } 1308 } 1309 }; 1310 1311 BS.event.on('quantity-discount:update', function(e) { 1312 replacePrices(e.level); 1313 }); 1314 })(); 1315 1316}); 1317 1318$(window).click(function() { 1319 let large_selector = $(".energy-tag-large-container"); 1320 if(large_selector.is(':visible')) 1321 { 1322 large_selector.addClass('hidden'); 1323 } 1324}); 1325 1326$(document).on('click', '.energy-tag-container', function(){ 1327 event.stopPropagation(); 1328 let large_selector = $(".energy-tag-large-container"); 1329 if(large_selector.is(':visible')) 1330 { 1331 large_selector.addClass('hidden'); 1332 } 1333 else 1334 { 1335 large_selector.removeClass('hidden'); 1336 } 1337}); 1338 1339$(document).on('click', '.cookies-notify__detail_button', function(){ 1340 var detail_box_selector = $('.cookies-notify__detail_box'); 1341 var arrow_selector = $('#cookies-notify__detail_button_arrow'); 1342 if(detail_box_selector.is(':visible')) 1343 { 1344 detail_box_selector.addClass('hidden'); 1345 arrow_selector.html('<i class="fa fa-chevron-down"></i>'); 1346 } 1347 else 1348 { 1349 detail_box_selector.removeClass('hidden'); 1350 arrow_selector.html('<i class="fa fa-chevron-up"></i>'); 1351 } 1352}); 1353 1354$(document).on('click', '.cookies-notify__cookie_type', function(){ 1355 var type = $(this).data('type'); 1356 var table_selector = $("#cookies-notify__cookie_detail_table tbody"); 1357 $(".cookie-active").removeClass('cookie-active'); 1358 $(this).addClass('cookie-active'); 1359 $.ajax( $.extend(true, {}, BS.Request.$default, { 1360 data: { 1361 action: "Cookies_notify", 1362 params: { 1363 request_type: 'cookie_list', 1364 type: type, 1365 }, 1366 }, 1367 success: function(response) { 1368 table_selector.empty(); 1369 $(".cookie_description_active").removeClass('cookie_description_active').addClass('hidden'); 1370 $("#cookie-notify__description_" + type).addClass('cookie_description_active').removeClass('hidden'); 1371 $(".cookie-notify__cookie_description").html(response.data.description); 1372 delete response.data.description; 1373 $.each(response.data, function(i, item){ 1374 table_selector.append("<tr>" + 1375 "<td>" + item.name + "</td>" + 1376 "<td>" + item.description + "</td>" + 1377 "<td>" + item.expires + "</td>"); 1378 }); 1379 1380 } 1381 })); 1382}); 1383$(document).on('click', '#cookies-nofify__close_detail, #cookies-notify__detail-close', function(){ 1384 $('.cookies-notify__detail_box').addClass('hidden'); 1385}); 1386 1387document.addEventListener("DOMContentLoaded", function(){ 1388 BS.multiples.ifNotISpinner(); 1389 1390 (function() { 1391 "use strict"; 1392 1393 var picker = document.getElementById('gift_picker'), 1394 form = document.getElementById('gift_picker_form'), 1395 gift_lists, 1396 selected_gift; 1397 if(!picker) return; 1398 gift_lists = picker.querySelectorAll('.gift-picker__list'); 1399 1400 // Palladium ponechava uz vybrane darky v nabidce, opakovany klik by skoncil chybou 1401 var keep_selected = !!(window.BS && BS.Design && BS.Design.template 1402 && BS.Design.template.is_selected('palladium')); 1403 1404 var selectGift = function(item, gift) { 1405 var id_input = form.querySelector('input[name="gift[id]"]'); 1406 var type_input = form.querySelector('input[name="gift[type]"]'); 1407 item.classList.add('gift-picker__item--selected'); 1408 if(id_input && type_input) { 1409 id_input.value = gift.id; 1410 type_input.value = gift.type; 1411 selected_gift = gift; 1412 1413 var radio = item.querySelector('.gift-picker__check'); 1414 if(radio) { 1415 radio.checked = true; 1416 } 1417 form.requestSubmit(); 1418 } 1419 }; 1420 1421 var selectHandler = function(e) { 1422 var gift, 1423 item = e.target.closest('.gift-picker__item'); 1424 if(!item) return; 1425 if(keep_selected && item.classList.contains('gift-picker__item--selected')) return; 1426 1427 try { 1428 gift = item && JSON.parse(item.dataset.gift); 1429 } catch(err) { 1430 console.error(err); 1431 gift = null; 1432 } 1433 1434 if(gift) { 1435 selectGift(item, gift); 1436 } 1437 } 1438 1439 $(gift_lists).on('click', ':not(.gift-picker__link)', selectHandler); 1440 form.addEventListener('submit', function(e) { 1441 if(!selected_gift) { 1442 e.preventDefault(); 1443 return; 1444 } 1445 }); 1446 1447 if($.fn.owlCarousel) { 1448 var items_xs = gift_lists.length 1449 ? parseInt(window.getComputedStyle(gift_lists[0]).getPropertyValue('--gift-items-xs'), 10) || 1 1450 : 1; 1451 var syncWidth = function() { 1452 var $list = $(this), width = $list.width(), owl = $list.data('owl.carousel'); 1453 if(owl && $list.data('measured-width') !== width) { 1454 $list.data('measured-width', width); 1455 owl.invalidate('width'); 1456 owl.refresh(); 1457 } 1458 }; 1459 $(gift_lists).on('refreshed.owl.carousel', syncWidth); 1460 $(gift_lists).owlCarousel({ 1461 loop:false, 1462 lazyLoad: false, 1463 margin:16, 1464 nav:true, 1465 onLoadLazy: true, 1466 responsive:{ 1467 0:{ 1468 items: 1 1469 }, 1470 300:{ 1471 items: items_xs 1472 }, 1473 480:{ 1474 items: 2 1475 }, 1476 960:{ 1477 items: 3 1478 }, 1479 1230:{ 1480 items: 6 1481 } 1482 } 1483 }); 1484 $(gift_lists).each(syncWidth); 1485 } 1486 })(); 1487 1488 (function() { 1489 "use strict"; 1490 1491 const widgets = new WeakMap(); 1492 const popupEl = document.getElementById('wishlist_popup'); 1493 let api, popup; 1494 1495 class WishlistApi { 1496 addProduct(data) { 1497 return new Promise(function(resolve, reject) { 1498 const request = BS.extend(BS.Request.$default, { 1499 data: { 1500 action: "Wishlist\\Controller", 1501 id_zakaznik: BS.User.id, 1502 params: { 1503 action: 'add_product', 1504 data: data 1505 }, 1506 }, 1507 success: function(response) { 1508 if(response.success) { 1509 resolve({ 1510 response: response.data, 1511 data, 1512 }); 1513 } else { 1514 reject(new Error(response.error || WA.Translation._wishlist_save_error)); 1515 } 1516 }, 1517 error: function(xhr, status, error) { 1518 reject(new Error(error || WA.Translation._wishlist_save_error)); 1519 } 1520 }); 1521 $.ajax(request); 1522 }); 1523 } 1524 1525 removeProduct(data) { 1526 return new Promise(function(resolve, reject) { 1527 const request = BS.extend(BS.Request.$default, { 1528 data: { 1529 action: "Wishlist\\Controller", 1530 id_zakaznik: BS.User.id, 1531 params: { 1532 action: 'remove_product', 1533 data: data 1534 }, 1535 }, 1536 success: function(response) { 1537 if(response.success) { 1538 resolve({ 1539 response: response.data, 1540 data, 1541 }); 1542 } else { 1543 reject(new Error(response.error || WA.Translation._wishlist_save_error)); 1544 } 1545 }, 1546 error: function(xhr, status, error) { 1547 reject(new Error(error || WA.Translation._wishlist_save_error)); 1548 } 1549 }); 1550 $.ajax(request); 1551 }); 1552 } 1553 1554 getProductWishlists(product) { 1555 return new Promise((resolve, reject) => { 1556 const request = BS.extend(BS.Request.$default, { 1557 data: { 1558 action: "Wishlist\\Controller", 1559 id_zakaznik: BS.User.id, 1560 params: { 1561 action: 'get_product_wishlists', 1562 data: product 1563 }, 1564 }, 1565 success: function(response) { 1566 if(response.success) { 1567 resolve({ 1568 response: response.data, 1569 product, 1570 }); 1571 } else { 1572 reject(new Error(response.error || WA.Translation._wishlist_save_error)); 1573 } 1574 }, 1575 error: function(xhr, status, error) { 1576 reject(new Error(error || WA.Translation._wishlist_save_error)); 1577 }, 1578 }); 1579 $.ajax(request); 1580 }); 1581 } 1582 } 1583 1584 class WishlistPopup { 1585 messageTimer = null; 1586 enabled = false;
1587 1588 constructor(popup, api) { 1589 this.popup = popup; 1590 this.widget = null; 1591 this.api = api; 1592 this.init(); 1593 } 1594 1595 init() { 1596 this.enabled = !this.popup.dataset.hasOwnProperty('wishlistDisabled'); 1597 if(this.enabled) { 1598 const form = this.popup.querySelector('form'); 1599 form.addEventListener('submit', this.onSubmitHandler.bind(this)); 1600 const list = this.popup.querySelector('.wishlists'); 1601 list.addEventListener('change', this.onWishlistChange.bind(this)); 1602 this.list = list; 1603 this.popup.querySelector('.wishlist-popup__new').addEventListener('click', this.showNameInput.bind(this)); 1604 } 1605 //outside click 1606 document.addEventListener('click', this.onDocumentClick.bind(this)); 1607 } 1608 1609 onDocumentClick(e) { 1610 if(!this.popup || !this.popup.classList.contains('wishlist-popup--show')) { 1611 return; 1612 } 1613 1614 const target = e.target; 1615 if(!this.popup.contains(target) && !this.widget.button.contains(target)) { 1616 this.popup.classList.remove('wishlist-popup--show'); 1617 if(this.enabled) { 1618 this.resetControls(); 1619 } 1620 this.widget = null; 1621 } 1622 } 1623 1624 onWishlistChange(e) { 1625 const checkbox = e.target; 1626 const wishlist = checkbox.closest('[data-wishlist]'); 1627 const idWishlist = parseInt(wishlist.dataset.wishlist); 1628 if(checkbox.checked) { 1629 this.api.addProduct(this.mergeSaveData({ id_wishlist: idWishlist })) 1630 .then(this.onAddSuccess.bind(this, null)) 1631 .catch(this.onSaveError.bind(this)) 1632 ; 1633 } else { 1634 this.api.removeProduct(this.mergeSaveData({ id_wishlist: idWishlist })) 1635 .then(this.onRemoveSuccess.bind(this)) 1636 .catch(this.onSaveError.bind(this)) 1637 ; 1638 } 1639 } 1640 1641 onSubmitHandler(e) { 1642 e.preventDefault(); 1643 const name = this.getNameInput().value.trim(); 1644 if(name === '') { 1645 return; 1646 } 1647 1648 this.api.addProduct(this.mergeSaveData({ name })) 1649 .then(this.onAddSuccess.bind(this, name)) 1650 .catch(this.onSaveError.bind(this)) 1651 ; 1652 } 1653 1654 showNameInput() { 1655 this.resetNameInput(); 1656 this.toggleNameControls(false); 1657 } 1658 1659 getNameInput() { 1660 return this.popup.querySelector('input[name="wishlist_name"]'); 1661 } 1662 1663 resetNameInput() { 1664 const nameInput = this.getNameInput(); 1665 if(nameInput) { 1666 nameInput.value = ''; 1667 } 1668 } 1669 1670 toggleNameControls(btnVisible = true) { 1671 const newBtn = this.popup.querySelector('.wishlist-popup__new'); 1672 const nameInput = this.popup.querySelector('.wishlist-popup__name'); 1673 if(btnVisible) { 1674 newBtn.style.display = ''; 1675 nameInput.style.display = 'none'; 1676 } else { 1677 newBtn.style.display = 'none'; 1678 nameInput.style.display = ''; 1679 } 1680 } 1681 1682 resetControls() { 1683 this.toggleNameControls(true); 1684 this.resetNameInput(); 1685 } 1686 1687 mergeSaveData(data) { 1688 const wishlistData = this.widget.data; 1689 1690 return Object.assign({}, data, { 1691 id_product: wishlistData.id_product, 1692 id_variant: wishlistData.id_variant, 1693 }); 1694 } 1695 1696 onAddSuccess(name, { response }) { 1697 if(response.created) { 1698 BS.Fce.call_conversion_request('add_to_wishlist', { 1699 product_id: this.widget.data.id_product, 1700 variant_id: this.widget.data.id_variant, 1701 count: 1 1702 }); 1703 } 1704 const wishlists = this.widget.data.wishlists; 1705 const index = wishlists.indexOf(response.id_wishlist); 1706 if(index === -1) { 1707 wishlists.push(response.id_wishlist) 1708 if(name) { 1709 const wishlistRow = this.getWishlistRow(response.id_wishlist); 1710 if(wishlistRow) { 1711 const checkbox = wishlistRow.querySelector('input[type="checkbox"]'); 1712 if(checkbox) { 1713 checkbox.checked = true; 1714 } 1715 } else { 1716 this.addItemToList(name, response.id_wishlist); 1717 } 1718 } 1719 } 1720 this.resetControls(); 1721 this.widget.onChange(); 1722 } 1723 1724 getWishlistRow(id) { 1725 return this.popup.querySelector(`[data-wishlist="${id}"]`); 1726 } 1727 1728 addItemToList(name, id) { 1729 const template = this.list.dataset.wishlistTemplate; 1730 this.list.insertAdjacentHTML('beforeend', template.replace('__name__', name).replace('__id__', id)); 1731 } 1732 1733 onRemoveSuccess({ data }) { 1734 const wishlists = this.widget.data.wishlists; 1735 const index = wishlists.indexOf(data.id_wishlist); 1736 if(index !== -1) { 1737 wishlists.splice(index, 1); 1738 } 1739 this.widget.onChange(); 1740 } 1741 1742 onSaveError(error) { 1743 console.error(error); 1744 } 1745 1746 show(widget) { 1747 if(this.widget === widget) { 1748 return; 1749 } 1750 1751 this.widget = widget; 1752 if(this.enabled) { 1753 this.resetControls(); 1754 this.updateList(widget); 1755 } 1756 1757 const arrowEl = this.popup.querySelector('.wishlist-popup__arrow'); 1758 this.popup.classList.add('wishlist-popup--show'); 1759 window.FloatingUIDOM.computePosition(widget.button, this.popup, { 1760 placement: 'bottom-center', 1761 middleware: [ 1762 window.FloatingUIDOM.offset({ 1763 mainAxis: 10, // 10px offset from the button 1764 crossAxis: 0, // no offset on the cross axis 1765 }), 1766 window.FloatingUIDOM.autoPlacement(), 1767 window.FloatingUIDOM.arrow({ element: arrowEl, padding: 10 }), 1768 ], 1769 }).then(({ x, y, middlewareData, placement }) => { 1770 Object.assign(this.popup.style, { 1771 left: `${x}px`, 1772 top: `${y}px`, 1773 }); 1774 1775 const arrowPlacementClass = `wishlist-popup__arrow--${placement.split('-')[0]}`; 1776 arrowEl.className = `wishlist-popup__arrow ${arrowPlacementClass}`; 1777 1778 if (middlewareData.arrow) { 1779 const {x : arrowX, y : arrowY} = middlewareData.arrow; 1780 Object.assign(arrowEl.style, { 1781 left: arrowX != null ? `${arrowX}px` : '', 1782 top: arrowY != null ? `${arrowY}px` : '', 1783 }); 1784 } 1785 }); 1786 } 1787 1788 updateList(widget) { 1789 this.list.innerHTML = ''; 1790 this.popup.classList.add('wishlist-popup--loading'); 1791 this.api.getProductWishlists(widget.data) 1792 .then(({ response }) => { 1793 this.widget.data.wishlists = response.wishlists.filter(w =>
1793 w.active).map(w => w.id); 1794 this.list.insertAdjacentHTML('afterbegin', response.html); 1795 }) 1796 .catch(err => { 1797 console.error(err); 1798 this.showErrorMessage(); 1799 }) 1800 .finally(() => { 1801 this.popup.classList.remove('wishlist-popup--loading'); 1802 }) 1803 ; 1804 } 1805 } 1806 1807 class WishlistWidget { 1808 constructor(button, popup, api) { 1809 this.button = button; 1810 this.popup = popup; 1811 this.init(); 1812 } 1813 1814 init() { 1815 const button = this.button; 1816 button.addEventListener('click', this.showPopup.bind(this)); 1817 this.data = JSON.parse(button.dataset.wishlist || '{}'); 1818 } 1819 1820 showPopup(event) { 1821 event.preventDefault(); 1822 event.stopPropagation(); 1823 this.popup.show(this); 1824 } 1825 1826 onChange() { 1827 const isEmpty = this.data.wishlists.length === 0; 1828 if(isEmpty) { 1829 this.button.classList.remove('wishlist-button--fill'); 1830 } else { 1831 this.button.classList.add('wishlist-button--fill'); 1832 } 1833 this.updateIcon(!isEmpty); 1834 } 1835 1836 updateIcon(fill) { 1837 const property = `icon${fill ? 'Solid' : 'Empty'}`; 1838 this.button.querySelector('.wishlist-button__icon').innerHTML = this.button.dataset[property]; 1839 } 1840 } 1841 1842 var initWishlistButtons = function(popup) { 1843 const buttons = document.querySelectorAll('.wishlist-button'); 1844 for(const button of buttons) { 1845 if(!button || widgets.has(button)) continue; 1846 widgets.set(button, new WishlistWidget(button, popup)); 1847 } 1848 }; 1849 1850 if(popupEl) { 1851 api = new WishlistApi(); 1852 popup = new WishlistPopup(popupEl, api); 1853 initWishlistButtons(popup); 1854 } 1855 1856 BS.Wishlist = { 1857 initButtons: function() { 1858 if(popup) { 1859 initWishlistButtons(popup); 1860 } 1861 } 1862 }; 1863 })(); 1864 1865 // Watchdog button in productList (product variants table on detail page) â Palladium only 1866 document.addEventListener('click', function(e) { 1867 var btn = e.target.closest('.watchdog-productlist-btn[data-watchdog-product-id]'); 1868 if (!btn) return; 1869 e.preventDefault(); 1870 var form = document.getElementById('watch_dog_form'); 1871 if (form) { 1872 var idProductInput = form.querySelector('input[name="id_product"]'); 1873 var isVariantInput = form.querySelector('input[name="is_variant"]'); 1874 var productUrlInput = form.querySelector('input[name="product_url"]'); 1875 var priceInput = form.querySelector('input[name="price_value"]'); 1876 if (idProductInput) idProductInput.value = btn.dataset.watchdogProductId; 1877 if (isVariantInput) isVariantInput.value = btn.dataset.watchdogIsVariant; 1878 if (productUrlInput) productUrlInput.value = btn.dataset.watchdogProductUrl; 1879 if (priceInput && btn.dataset.watchdogPrice) priceInput.value = btn.dataset.watchdogPrice; 1880 } 1881 var trigger = document.getElementById('open_watch_dog'); 1882 if (trigger) trigger.click(); 1883 }); 1884 1885 (function(BS, document) { 1886 "use strict"; 1887 1888 const wishlistPageApp = document.getElementById('wishlist-page'); 1889 if(!wishlistPageApp) return; 1890 1891 const addListModal = document.getElementById('wishlist_create_modal'); 1892 const confirmModal = document.getElementById('wishlist_confirm_modal'); 1893 let confirmAction = null; 1894 const tabs = wishlistPageApp.querySelector('.tabs'); 1895 let tabInstance = null; 1896 if(tabs) { 1897 tabInstance = new BS.Tab(wishlistPageApp.querySelector('.tabs')); 1898 } 1899 1900 const addToBasket = event => { 1901 const form = event.target; 1902 const basketVersion = BS.Basket.variant(); 1903 switch(basketVersion) { 1904 case 2: 1905 case 3: 1906 event.preventDefault();
1907 buy_event($(form), 1); 1908 break; 1909 case 4: 1910 event.preventDefault(); 1911 run_basket_fuctionality(form); 1912 break; 1913 case 6: 1914 event.preventDefault(); 1915 break; 1916 } 1917 }; 1918 1919 const confirmHandler = e => { 1920 if(confirmAction) { 1921 confirmAction(e); 1922 } 1923 }; 1924 1925 const cancelHanlder = e => { 1926 $.magnificPopup.close(); 1927 }; 1928 1929 const confirm = (message, onConfirm) => { 1930 confirmModal.querySelector('[data-wishlist-confirm-message]').innerHTML = message; 1931 confirmAction = onConfirm; 1932 $.magnificPopup.open({ 1933 items: { 1934 src: $(confirmModal) 1935 }, 1936 modal: true, 1937 closeOnBgClick: true, 1938 showCloseBtn: true, 1939 callbacks: { 1940 close: () => { 1941 confirmAction = null; 1942 }, 1943 } 1944 }); 1945 }; 1946 1947 const showNoListMessage = () => { 1948 wishlistPageApp.insertAdjacentHTML('beforeend', wishlistPageApp.dataset.wishlistTemplateNoList); 1949 }; 1950 1951 const hideDialog = () => { 1952 $.magnificPopup.close(); 1953 }; 1954 1955 const removeList = btn => { 1956 const listId = btn.dataset.wishlistRemove; 1957 const request = BS.extend(BS.Request.$default, { 1958 data: { 1959 action: "Wishlist\\Controller", 1960 id_zakaznik: BS.User.id, 1961 params: { 1962 action: 'remove_list', 1963 data: { 1964 id: listId, 1965 } 1966 }, 1967 }, 1968 success: function(response) { 1969 if(response.success) { 1970 const navItem = btn.closest('.nav-item'); 1971 if(navItem) { 1972 navItem.remove(); 1973 } 1974 1975 const tabPane = wishlistPageApp.querySelector(`[data-wishlist-id="${listId}"]`); 1976 if(tabPane) { 1977 tabPane.remove(); 1978 } 1979 1980 if(wishlistPageApp.querySelectorAll('[data-wishlist-id]').length > 0) { 1981 //pokud neni zadna zalozka aktivni, zvolime prvni 1982 if(!tabs.querySelector('.nav-item.active')) { 1983 const firstTab = wishlistPageApp.querySelector('.nav-item'); 1984 if(firstTab) { 1985 tabInstance.show(firstTab.querySelector('.nav-link')); 1986 } 1987 } 1988 } else { 1989 showNoListMessage(); 1990 } 1991 hideDialog(); 1992 } 1993 }, 1994 error: function(xhr, status, error) { 1995 console.error("Error removing wishlist:", error); 1996 hideDialog(); 1997 } 1998 }); 1999 $.ajax(request); 2000 }; 2001 2002 const removeItem = btn => { 2003 const itemId = btn.dataset.wishlistRemoveItem; 2004 const request = BS.extend(BS.Request.$default, { 2005 data: { 2006 action: "Wishlist\\Controller", 2007 id_zakaznik: BS.User.id, 2008 params: { 2009 action: 'remove_product', 2010 data: { 2011 id: itemId, 2012 return_html: true, 2013 } 2014 }, 2015 }, 2016 success: function(response) { 2017 if(response.success) { 2018 const row = btn.closest('.wishlist-product'); 2019 const tabPane = btn.closest('.tab-pane'); 2020 if(row) { 2021 row.remove(); 2022 } 2023 2024 if(tabPane.querySelectorAll('.wishlist-product').length > 0) { 2025 const totalPriceEl = tabPane.querySelector('.wishlist-total-price'); 2026 totalPriceEl.innerHTML = response.data.total_price_formatted; 2027 } else { 2028 tabPane.innerHTML = wishlistPageApp.dataset.wishlistTemplateNoItem; 2029 } 2030 } 2031 }, 2032 error: function(xhr, status, error) { 2033 console.error("Error removing wishlist item:", error); 2034 } 2035 }); 2036 $.ajax(request); 2037 }; 2038 2039 const showAddListModal = () => { 2040 $.magnificPopup.open({ 2041 items: { 2042 src: $(addListModal) 2043 }, 2044 modal: false, 2045 closeOnContentClick: false, 2046 closeOnBgClick: true, 2047 closeBtnInside: false, 2048 showCloseBtn: false, 2049 }); 2050 }; 2051 2052 const validateAddListForm = e => { 2053 const form = e.target; 2054 const nameField = form.querySelector('input[name="wishlist[name]"]'); 2055 if(!nameField) { 2056 e.preventDefault(); 2057 return; 2058 } 2059 2060 const name = nameField.value.trim(); 2061 if(name === '') { 2062 e.preventDefault(); 2063 return; 2064 } 2065 }; 2066 2067 const addAllItemsToBasket = async (e, btn) => { 2068 const list = btn.closest('[data-wishlist-id]'); 2069 if(!list) return; 2070 const rows = list.querySelectorAll('[data-wishlist-row]'); 2071 var requestData = new FormData(); 2072 for(const [index, row] of rows.entries()) { 2073 const rowForm = new FormData(row); 2074 const buyBtn = row.querySelector('[data-wishlist-buy-item]'); 2075 const variantId = rowForm.get('variant_selected'); 2076 requestData.append(`items[${index}][item]`, buyBtn.dataset.id); 2077 requestData.append(`items[${index}][item_variant]`, variantId); 2078 requestData.append(`items[${index}][variant_selected]`, variantId); 2079 requestData.append(`items[${index}][kusy]`, rowForm.get('kusy')); 2080 } 2081
2082 try { 2083 const response = await fetch(`/wa_script/basket_ajax.php?method=add&bulk=1&from_wishlist=1&id=${BS.User.id}`, { 2084 method: 'POST', 2085 body: requestData, 2086 }); 2087 if(!response.ok) { 2088 throw new Error(`HTTP error! status: ${response.status}`); 2089 } 2090 2091 const responseData = await response.json(); 2092 if(responseData.basket_url) { 2093 window.location.href = responseData.basket_url; 2094 } 2095 } catch(err) { 2096 console.error("Error preparing request data:", err); 2097 } 2098 }; 2099 2100 const nav = wishlistPageApp.querySelector('.nav-tabs'); 2101 if(nav) { 2102 nav.addEventListener('click', e => { 2103 const removeBtn = e.target.closest('[data-wishlist-remove]'); 2104 if(!removeBtn) return; 2105 2106 confirm(WA.Translation._wishlist_remove_confirm, () => { 2107 removeList(e.target); 2108 }); 2109 }); 2110 } 2111 2112 if(tabs) { 2113 tabs.addEventListener('click', e => { 2114 const removeBtn = e.target.closest('[data-wishlist-remove-item]'); 2115 if(removeBtn) { 2116 removeItem(removeBtn); 2117 } 2118 }); 2119 } 2120 wishlistPageApp.querySelector('[data-wishlist-add]').addEventListener('click', showAddListModal); 2121 addListModal.querySelector('[data-wishlist-add-form]').addEventListener('submit', validateAddListForm); 2122 confirmModal.querySelector('[data-wishlist-confirm]').addEventListener('click', confirmHandler); 2123 confirmModal.querySelector('[data-wishlist-cancel]').addEventListener('click', cancelHanlder); 2124 wishlistPageApp.addEventListener('submit', addToBasket); 2125 wishlistPageApp.addEventListener('click', e => { 2126 const btn = e.target.closest('[data-wishlist-buy-all]'); 2127 if(btn) { 2128 addAllItemsToBasket(e, btn); 2129 } 2130 }); 2131 wishlistPageApp.addEventListener('click', e => { 2132 const btn = e.target.closest('[data-watchdog-product-id]'); 2133 if(!btn) return; 2134 e.preventDefault(); 2135 const form = document.getElementById('watch_dog_form'); 2136 if(form) { 2137 const idProductInput = form.querySelector('input[name="id_product"]'); 2138 const isVariantInput = form.querySelector('input[name="is_variant"]'); 2139 const productUrlInput = form.querySelector('input[name="product_url"]'); 2140 if(idProductInput) idProductInput.value = btn.dataset.watchdogProductId; 2141 if(isVariantInput) isVariantInput.value = btn.dataset.watchdogIsVariant; 2142 if(productUrlInput) productUrlInput.value = btn.dataset.watchdogProductUrl; 2143 } 2144 const trigger = document.getElementById('open_watch_dog'); 2145 if(trigger) trigger.click(); 2146 }); 2147 }).apply(this, [BS, document]); 2148}); 2149 2150document.addEventListener('DOMContentLoaded', () => { 2151 const input = document.querySelector('#search input#q'); 2152 if (!input) return; 2153 2154 const words = (typeof WA_SEARCH_PLACEHOLDERS !== 'undefined' && Array.isArray(WA_SEARCH_PLACEHOLDERS) && WA_SEARCH_PLACEHOLDERS.length > 0) 2155 ? WA_SEARCH_PLACEHOLDERS 2156 : null; 2157 2158 if (!words) return; 2159 2160 const typingSpeed = 80; 2161 const deletingSpeed = 50; 2162 const pauseAfterType = 1200; 2163 2164 let wordIndex = 0; 2165 let charIndex = 0; 2166 let isDeleting = false; 2167 2168 function animatePlaceholder() { 2169 // pokud je input aktivnà nebo obsahuje text, animaci stopni 2170 if (document.activeElement === input || input.value.length) { 2171 setTimeout(animatePlaceholder, 300); 2172 return; 2173 } 2174 2175 const word = words[wordIndex]; 2176 2177 if (!isDeleting) { 2178 charIndex++; 2179 input.placeholder = word.slice(0, charIndex); 2180 2181 if (charIndex === word.length) { 2182 setTimeout(() => isDeleting = true, pauseAfterType); 2183 } 2184 } else { 2185 charIndex--; 2186 input.placeholder = word.slice(0, charIndex); 2187 2188 if (charIndex === 0) { 2189 isDeleting = false; 2190 wordIndex = (wordIndex + 1) % words.length; 2191 } 2192 } 2193 2194 setTimeout( 2195 animatePlaceholder, 2196 isDeleting ? deletingSpeed : typingSpeed 2197 ); 2198 } 2199 2200 animatePlaceholder(); 2201});
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.