1"use strict"; 2 3function _objectValues(obj) { 4 var values = []; 5 var keys = Object.keys(obj); 6 7 for (var k = 0; k < keys.length; k++) values.push(obj[keys[k]]); 8 9 return values; 10} 11 12function _objectEntries(obj) { 13 var entries = []; 14 var keys = Object.keys(obj); 15 16 for (var k = 0; k < keys.length; k++) entries.push([keys[k], obj[keys[k]]]); 17 18 return entries; 19} 20 21function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 22 23function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } 24 25function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } 26 27function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 28 29function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } 30 31function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } 32 33function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } 34 35function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 36 37function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } 38 39function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } 40 41function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 42 43function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } 44 45function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 46 47function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 48 49function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } 50 51/******************************* 52 * Recras integration library * 53 * v 2.0.6 * 54 *******************************/ 55var RecrasBooking = /*#__PURE__*/function () { 56 function RecrasBooking() { 57 var _this = this; 58 59 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 60 61 _classCallCheck(this, RecrasBooking); 62 63 this.datePicker = null; 64 this.PAYMENT_DIRECT = 'mollie'; 65 this.PAYMENT_AFTERWARDS = 'factuur'; 66 this.RECRAS_INFINITY = 99999; // This is used instead of "true infinity" because JSON doesn't have infinity 67 68 this.languageHelper = new RecrasLanguageHelper(); 69 70 if (!(options instanceof RecrasOptions)) { 71 throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); 72 } 73 74 this.options = options; 75 this.eventHelper = new RecrasEventHelper(); 76 this.eventHelper.setAnalytics(this.options.getAnalytics()); 77 this.eventHelper.setEvents(this.options.getAnalyticsEvents());
78 var optionsPromise = this.languageHelper.setOptions(options); 79 this.element = this.options.getElement(); 80 this.element.classList.add('recras-onlinebooking'); 81 82 this.fetchJson = function (url) { 83 return RecrasHttpHelper.fetchJson(url, _this.error); 84 }; 85 86 this.postJson = function (url, data) { 87 return RecrasHttpHelper.postJson(_this.options.getApiBase() + url, data, _this.error.bind(_this)); 88 }; 89 90 if (this.options.getLocale()) { 91 if (!RecrasLanguageHelper.isValid(this.options.getLocale())) { 92 console.warn(this.languageHelper.translate('ERR_INVALID_LOCALE', { 93 LOCALES: RecrasLanguageHelper.validLocales.join(', ') 94 })); 95 } else { 96 this.languageHelper.setLocale(this.options.getLocale()); 97 } 98 } 99 100 if (this.options.getPreFilledAmounts()) { 101 if (!this.options.isSinglePackage()) { 102 console.warn(this.languageHelper.translate('ERR_AMOUNTS_NO_PACKAGE')); 103 } 104 } 105 106 if (this.options.getPreFilledDate()) { 107 this.prefillDateIfPossible(); 108 } 109 110 if (this.options.getPreFilledTime()) { 111 this.prefillTimeIfPossible(); 112 } 113 114 RecrasCSSHelper.loadCSS('global'); 115 RecrasCSSHelper.loadCSS('booking'); 116 RecrasCSSHelper.loadCSS('pikaday'); 117 this.clearAll(); 118 this.loadingIndicatorShow(this.element); 119 this.promise = optionsPromise.then(function () { 120 return RecrasCalendarHelper.loadScript(); 121 }).then(function () { 122 return _this.getTexts(); 123 }).then(function (texts) { 124 _this.texts = texts; 125 return _this.getPackages(); 126 }).then(function (packages) { 127 _this.loadingIndicatorHide(); 128 129 var pck = _this.options.getPackageId(); 130 131 if (_this.options.isSinglePackage()) { 132 if (Array.isArray(pck)) { 133 pck = pck[0]; 134 } 135 136 return _this.changePackage(pck); 137 } else if (Array.isArray(pck) && pck.length > 1) { 138 packages = packages.filter(function (p) { 139 return pck.includes(p.id); 140 }); 141 } 142 143 return _this.showPackages(packages); 144 }); 145 } 146 147 _createClass(RecrasBooking, [{ 148 key: "prefillDateIfPossible", 149 value: function prefillDateIfPossible() { 150 var date = new Date(this.options.getPreFilledDate()); 151 152 if (isNaN(date.getTime())) { 153 console.warn(this.languageHelper.translate('ERR_INVALID_DATE')); 154 return false; 155 } 156 157 if (date < new Date()) { 158 console.warn(this.languageHelper.translate('ERR_DATE_PAST')); 159 return false; 160 } 161 162 if (!this.options.isSinglePackage()) { 163 console.warn(this.languageHelper.translate('ERR_DATE_NO_SINGLE_PACKAGE')); 164 return false; 165 } 166 167 this.prefilledDate = date; 168 return true; 169 } 170 }, { 171 key: "prefillTimeIfPossible", 172 value: function prefillTimeIfPossible() { 173 var time = this.options.getPreFilledTime(); 174 175 if (!time.match(/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/)) { 176 console.warn(this.languageHelper.translate('ERR_INVALID_TIME')); 177 return false; 178 } 179 180 this.prefilledTime = time; 181 return true; 182 } 183 }, { 184 key: "hasAtLeastOneProduct", 185 value: function hasAtLeastOneProduct(pack) { 186 if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { 187 return true; 188 } 189 190 var hasAtLeastOneProduct = false; 191 192 for (var _i2 = 0, _this$getLinesNoBooki2 = this.getLinesNoBookingSize(pack); _i2 < _this$getLinesNoBooki2.length; _i2++) { 193 var line = _this$getLinesNoBooki2[_i2]; 194 var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); 195 196 if (lineEl && lineEl.value > 0) { 197 hasAtLeastOneProduct = true; 198 } 199 } 200 201 return hasAtLeastOneProduct; 202 } 203 }, {
204 key: "amountsValid", 205 value: function amountsValid(pack) { 206 for (var _i4 = 0, _this$getLinesNoBooki4 = this.getLinesNoBookingSize(pack); _i4 < _this$getLinesNoBooki4.length; _i4++) { 207 var line = _this$getLinesNoBooki4[_i4]; 208 var lineEl = this.findElement("[data-package-id=\"".concat(line.id, "\"]")); 209 210 if (!lineEl) { 211 console.warn("Element for line ".concat(line.id, " not found")); 212 return false; 213 } 214 215 var aantal = lineEl.value; 216 217 if (aantal > 0 && aantal < line.aantal_personen) { 218 return false; 219 } 220 221 if (aantal > 0 && line.min && aantal < line.min) { 222 return false; 223 } 224 225 if (line.max && aantal > line.max) { 226 return false; 227 } 228 } 229 230 if (this.shouldShowBookingSize(pack) && this.bookingSize() > 0) { 231 if (this.bookingSize() < this.bookingSizeMinimum(pack) || this.bookingSize() > this.bookingSizeMaximum(pack)) { 232 return false; 233 } 234 } 235 236 return this.hasAtLeastOneProduct(pack); 237 } 238 }, { 239 key: "appendHtml", 240 value: function appendHtml(msg) { 241 this.element.insertAdjacentHTML('beforeend', msg); 242 } 243 }, { 244 key: "applyVoucher", 245 value: function applyVoucher(packageID, voucherCode) { 246 var _this2 = this; 247 248 if (!voucherCode) { 249 this.setDiscountStatus(this.languageHelper.translate('VOUCHER_EMPTY')); 250 return Promise.resolve(false); 251 } 252 253 if (this.appliedVouchers[voucherCode]) { 254 this.setDiscountStatus(this.languageHelper.translate('VOUCHER_ALREADY_APPLIED')); 255 return Promise.resolve(false); 256 } 257 258 if (!this.selectedDate) { 259 this.setDiscountStatus(this.languageHelper.translate('DATE_INVALID')); 260 return Promise.resolve(false); 261 } 262 263 return this.postJson('onlineboeking/controleervoucher', { 264 arrangement_id: packageID, 265 datum: RecrasDateHelper.datePartOnly(this.selectedDate), 266 producten: this.productCounts(), 267 vouchers: [voucherCode] 268 }).then(function (json) { 269 var result = json[voucherCode]; 270 271 if (!result.valid) { 272 return Promise.resolve(false); 273 } 274 275 _this2.appliedVouchers[voucherCode] = result.processed; 276 277 _this2.showTotalPrice(); 278 279 return true; 280 }); 281 } 282 }, { 283 key: "recheckDiscountCode", 284 value: function recheckDiscountCode() { 285 var _this3 = this; 286 287 this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.discount.code).then(function (status) { 288 if (status) { 289 _this3.setDiscountStatus(_this3.languageHelper.translate('DISCOUNT_APPLIED'), false); 290 } else { 291 _this3.discount = null; 292 293 _this3.showTotalPrice(); 294 295 var statusEl = _this3.findElement('.discount-status'); 296 297 if (statusEl) { 298 statusEl.parentNode.removeChild(statusEl); 299 } 300 } 301 }); 302 } 303 }, { 304 key: "recheckVouchers", 305 value: function recheckVouchers() { 306 var voucherCodes = Object.keys(this.appliedVouchers); 307 this.appliedVouchers = []; 308 var promises = []; 309 310 for (var _i6 = 0; _i6 < voucherCodes.length; _i6++) { 311 var voucherCode = voucherCodes[_i6]; 312 promises.push(this.applyVoucher(this.selectedPackage.id, voucherCode)); 313 } 314 315 return Promise.all(promises); 316 } 317 }, { 318 key: "bookingSize", 319 value: function bookingSize() { 320 var bookingSizeEl = this.findElement('.bookingsize'); 321 322 if (!bookingSizeEl) { 323 return 0; 324 } 325 326 var bookingSizeValue = parseInt(bookingSizeEl.value, 10); 327 328 if (isNaN(bookingSizeValue)) { 329 return 0; 330 } 331 332 return bookingSizeValue; 333 } 334 }, {
335 key: "bookingSizeLines", 336 value: function bookingSizeLines(pack) { 337 return pack.regels.filter(function (line) { 338 return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; 339 }); 340 } 341 }, { 342 key: "bookingSizeMaximum", 343 value: function bookingSizeMaximum(pack) { 344 var lines = this.bookingSizeLines(pack).filter(function (line) { 345 return line.max; 346 }); 347 348 if (lines.length === 0) { 349 return this.RECRAS_INFINITY; 350 } 351 352 var maxes = lines.map(function (line) { 353 return line.max; 354 }); 355 return Math.min.apply(Math, _toConsumableArray(maxes)); 356 } 357 }, { 358 key: "bookingSizeLineMinimum", 359 value: function bookingSizeLineMinimum(line) { 360 if (line.min) { 361 return line.min; 362 } 363 364 if (line.onlineboeking_aantalbepalingsmethode === 'vast') { 365 return 0; 366 } 367 368 return line.product.minimum_aantal; 369 } 370 }, { 371 key: "bookingSizeMinimum", 372 value: function bookingSizeMinimum(pack) { 373 var _this4 = this; 374 375 var minSize = 0; 376 this.bookingSizeLines(pack).forEach(function (line) { 377 minSize = Math.max(minSize, _this4.bookingSizeLineMinimum(line)); 378 }); 379 return minSize; 380 } 381 }, { 382 key: "amountFromPersons", 383 value: function amountFromPersons(product, persons) { 384 return persons; //TODO: this doesn't work yet because public product API does not send: 385 // aantalbepaling, aantal, per_x_personen_afronding, per_x_personen 386 387 if (product.aantalbepaling === 'vast') { 388 return product.aantal; 389 } 390 391 var fn = product.per_x_personen_afronding === 'beneden' ? Math.floor : Math.ceil; 392 return product.aantal * fn(persons / product.per_x_personen); 393 } 394 }, { 395 key: "bookingSizePrice", 396 value: function bookingSizePrice(pack) { 397 var _this5 = this; 398 399 var nrOfPersons = Math.max(pack.aantal_personen, 1); 400 var price = 0; 401 var lines = this.bookingSizeLines(pack); 402 lines.forEach(function (line) { 403 price += Math.max(_this5.amountFromPersons(line.product, nrOfPersons), line.product.minimum_aantal) * parseFloat(line.product.verkoop); 404 }); 405 return price / nrOfPersons; 406 } 407 }, { 408 key: "filterPackagesFromoptions", 409 value: function filterPackagesFromoptions(packages) { 410 var pck = this.options.getPackageId(); 411 412 if (!Array.isArray(pck)) { 413 return packages; 414 } 415 416 return packages.filter(function (p) { 417 return pck.includes(p.id); 418 }); 419 } 420 }, { 421 key: "changePackage", 422 value: function changePackage(packageID) { 423 var _this6 = this; 424 425 var selectedPackage = this.packages.filter(function (p) { 426 return p.id === packageID; 427 }); 428 this.appliedVouchers = {}; 429 this.discount = null; 430 431 if (selectedPackage.length === 0) { 432 // Reset form 433 this.selectedPackage = null; 434 this.clearAll(); 435 var packages = this.filterPackagesFromoptions(this.packages); 436 this.showPackages(packages); 437 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_RESET); 438 return Promise.resolve(false); 439 } else { 440 this.clearAllExceptPackageSelection(); 441 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, selectedPackage[0].arrangement, selectedPackage[0].id, { 442 content_type: 'package', 443 item_id: selectedPackage[0].id 444 }); 445 } 446 447 this.selectedPackage = selectedPackage[0]; 448 return this.showProducts(this.selectedPackage).then(function () { 449 _this6.nextSectionActive('.recras-package-select', '.recras-amountsform'); 450 451 _this6.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PRODUCTS_SHOWN); 452 453 if (_this6.options.getAutoScroll() === true) { 454 var scrollOptions = { 455 behavior: 'smooth' 456 }; 457 458 if (!('scrollBehavior' in document.documentElement.style)) { 459 scrollOptions = true; 460 } 461
462 _this6.findElement('.recras-amountsform').scrollIntoView(scrollOptions); 463 } 464 465 _this6.checkDependencies(); 466 467 _this6.loadingIndicatorShow(_this6.findElement('.recras-amountsform')); 468 469 return _this6.showDateTimeSelection(_this6.selectedPackage); 470 }).then(function () { 471 _this6.loadingIndicatorHide(); 472 473 _this6.showContactForm(_this6.selectedPackage); 474 }); 475 } 476 }, { 477 key: "checkBookingSize", 478 value: function checkBookingSize(pack) { 479 if (!this.shouldShowBookingSize(pack)) { 480 return; 481 } 482 483 var bookingSize = this.bookingSize(); 484 var bsMaximum = this.bookingSizeMaximum(pack); 485 var bsMinimum = this.bookingSizeMinimum(pack); 486 487 if (bookingSize < bsMinimum) { 488 this.setMinMaxAmountWarning('bookingsize', bsMinimum, 'minimum'); 489 } else if (bookingSize > bsMaximum) { 490 this.setMinMaxAmountWarning('bookingsize', bsMaximum, 'maximum'); 491 } 492 493 this.maybeDisableBookButton(); 494 } 495 }, { 496 key: "checkDependencies", 497 value: function checkDependencies() { 498 var _this7 = this; 499 500 _toConsumableArray(this.findElements('.recras-product-dependency')).forEach(function (el) { 501 el.parentNode.removeChild(el); 502 }); 503 504 _toConsumableArray(this.findElements('[data-package-id]')).forEach(function (el) { 505 el.classList.remove('recras-input-invalid'); 506 }); 507 508 this.requiresProduct = false; 509 this.productCounts().forEach(function (line) { 510 if (line.aantal > 0) { 511 var packageLineID = line.arrangementsregel_id; 512 513 var product = _this7.findProduct(packageLineID).product; 514 515 var thisProductRequiresProduct = false; 516 517 if (!product.vereist_product) { 518 console.warn('You are logged in to this particular Recras. Because of API differences between logged-in and logged-out state, required products do not work as expected.'); 519 } else { 520 product.vereist_product.forEach(function (vp) { 521 if (!_this7.dependencySatisfied(line.aantal, vp)) { 522 thisProductRequiresProduct = true; 523 _this7.requiresProduct = true; 524 525 var requiredAmount = _this7.requiredAmount(line.aantal, vp); 526 527 var requiredProductName = _this7.getProductByID(vp.vereist_product_id).weergavenaam; 528 529 var message = _this7.languageHelper.translate('PRODUCT_REQUIRED', { 530 NUM: line.aantal, 531 PRODUCT: product.weergavenaam, 532 REQUIRED_AMOUNT: requiredAmount, 533 REQUIRED_PRODUCT: requiredProductName 534 }); 535 536 _this7.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "<span class=\"recras-product-dependency\">".concat(message, "</span>")); 537 } 538 }); 539 } 540 541 if (thisProductRequiresProduct) { 542 var productInput = _this7.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); 543 544 productInput.classList.add('recras-input-invalid'); 545 } 546 } 547 }); 548 this.maybeDisableBookButton(); 549 } 550 }, { 551 key: "checkDiscountAndVoucher", 552 value: function checkDiscountAndVoucher() { 553 var _this8 = this; 554 555 var discountPromise = this.checkDiscountcode(this.selectedPackage.id, RecrasDateHelper.datePartOnly(this.selectedDate), this.findElement('#discountcode').value.trim()); 556 var voucherPromise = this.applyVoucher(this.selectedPackage.id, this.findElement('#discountcode').value.trim()); 557 Promise.all([discountPromise, voucherPromise]).then(function (_ref) { 558 var _ref2 = _slicedToArray(_ref, 2), 559 discountStatus = _ref2[0], 560 voucherStatus = _ref2[1]; 561 562 if (discountStatus || voucherStatus) { 563 var status; 564 565 if (discountStatus) { 566 status = 'DISCOUNT_APPLIED'; 567 } else { 568 status = 'VOUCHER_APPLIED'; 569 } 570 571 _this8.setDiscountStatus(_this8.languageHelper.translate(status), false); 572 573 _this8.findElement('#discountcode').value = ''; 574 575 _this8.nextSectionActive('.recras-discounts', '.recras-contactform'); 576 } else { 577 _this8.setDiscountStatus(_this8.languageHelper.translate('DISCOUNT_INVALID')); 578 } 579 }); 580 } 581 }, {
582 key: "checkDiscountcode", 583 value: function checkDiscountcode(packageID, date, code) { 584 var _this9 = this; 585 586 return this.fetchJson(this.options.getApiBase() + 'onlineboeking/controleerkortingscode' + '?datum=' + date + '&arrangement=' + packageID + '&kortingscode=' + encodeURIComponent(code)).then(function (discount) { 587 if (discount === false) { 588 return false; 589 } 590 591 discount.code = code; 592 _this9.discount = discount; 593 594 _this9.showTotalPrice(); 595 596 return true; 597 }); 598 } 599 }, { 600 key: "checkMaximumForPackage", 601 value: function checkMaximumForPackage() { 602 var _this10 = this; 603 604 var maxPerLine = this.selectedPackage.maximum_aantal_personen_online; 605 606 if (maxPerLine === null) { 607 return Promise.resolve(null); 608 } 609 610 var showWarning = false; 611 var selectedProducts = this.productCounts(); 612 return this.languageHelper.filterTags(this.texts.maximum_aantal_online_boeking_overschreden, this.selectedPackage ? this.selectedPackage.id : null).then(function (msg) { 613 selectedProducts.forEach(function (p) { 614 if (p.aantal > maxPerLine && !showWarning) { 615 var input = _this10.findElement("[data-package-id=\"".concat(p.arrangementsregel_id, "\"]")); 616 617 if (!input) { 618 input = _this10.findElement('#bookingsize'); 619 } 620 621 if (input) { 622 var warningEl = document.createElement('div'); 623 warningEl.classList.add('maximum-amount'); 624 warningEl.classList.add('recras-full-width'); 625 warningEl.innerHTML = msg; 626 input.parentNode.parentNode.insertBefore(warningEl, input.parentNode.nextSibling); 627 input.classList.add('recras-input-invalid'); 628 } else { 629 _this10.findElement('.recras-amountsform').insertAdjacentHTML('beforeend', "<span class=\"maximum-amount\">".concat(msg, "</span>")); 630 } 631 632 showWarning = true; 633 } 634 }); 635 }); 636 } 637 }, { 638 key: "contactFormValid", 639 value: function contactFormValid() { 640 var contactFormIsValid = this.findElement('.recras-contactform').checkValidity(); 641 var contactFormRequiredCheckboxes = this.contactForm.checkRequiredCheckboxes(); 642 return contactFormIsValid && contactFormRequiredCheckboxes; 643 } 644 }, { 645 key: "setMinMaxAmountWarning", 646 value: function setMinMaxAmountWarning(lineID, minAmount) { 647 var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'minimum'; 648 var warnEl = document.createElement('span'); 649 warnEl.classList.add(type + '-amount'); 650 var lineEl = this.findElement("#".concat(lineID)); 651 652 if (!lineEl) { 653 console.warn("Element for line ".concat(lineID, " not found")); 654 return false; 655 } 656 657 lineEl.classList.add('recras-input-invalid'); 658 var text; 659 660 if (type === 'minimum') { 661 text = this.languageHelper.translate('PRODUCT_MINIMUM', { 662 MINIMUM: minAmount 663 }); 664 } else { 665 text = this.languageHelper.translate('PRODUCT_MAXIMUM', { 666 MAXIMUM: minAmount 667 }); 668 } 669 670 warnEl.innerHTML = text; 671 var label = this.findElement("label[for=\"".concat(lineID, "\"]")); 672 label.parentNode.appendChild(warnEl); 673 } 674 }, { 675 key: "checkMinMaxAmounts", 676 value: function checkMinMaxAmounts() {
677 for (var _i8 = 0, _this$productCounts2 = this.productCounts(); _i8 < _this$productCounts2.length; _i8++) { 678 var product = _this$productCounts2[_i8]; 679 680 if (product.aantal < 1) { 681 continue; 682 } 683 684 var packageLineID = product.arrangementsregel_id; 685 var packageLine = this.findProduct(packageLineID); 686 var input = this.findElement("[data-package-id=\"".concat(packageLineID, "\"]")); 687 688 if (!input) { 689 // This is a "booking size" line - this is handled in checkBookingSize 690 continue; 691 } 692 693 if (product.aantal < packageLine.product.minimum_aantal) { 694 this.setMinMaxAmountWarning(input.id, packageLine.product.minimum_aantal, 'minimum'); 695 } else if (packageLine.min !== undefined && product.aantal < packageLine.min) { 696 this.setMinMaxAmountWarning(input.id, packageLine.min, 'minimum'); 697 } else if (packageLine.max !== null && product.aantal > packageLine.max) { 698 this.setMinMaxAmountWarning(input.id, packageLine.max, 'maximum'); 699 } 700 } 701 } 702 }, { 703 key: "clearAll", 704 value: function clearAll() { 705 this.clearElements(this.element.children); 706 } 707 }, { 708 key: "clearAllExceptPackageSelection", 709 value: function clearAllExceptPackageSelection() { 710 var packageSelect = this.findElement('.recras-package-select'); 711 712 if (packageSelect) { 713 packageSelect.classList.remove('recras-completed'); 714 packageSelect.classList.add('recras-active'); 715 } 716 717 var elements = document.querySelectorAll('#' + this.element.id + ' > *:not(.recras-package-select)'); 718 this.clearElements(elements); 719 } 720 }, { 721 key: "clearElements", 722 value: function clearElements(elements) { 723 if (this.datePicker) { 724 this.datePicker.destroy(); 725 } 726 727 this.availableDays = []; 728 729 _toConsumableArray(elements).forEach(function (el) { 730 el.parentNode.removeChild(el); 731 }); 732 733 this.maybeAddLatestErrorElement(); 734 } 735 }, { 736 key: "dependencySatisfied", 737 value: function dependencySatisfied(hasNow, requiredProduct) {
738 for (var _i10 = 0, _this$productCounts4 = this.productCounts(); _i10 < _this$productCounts4.length; _i10++) { 739 var line = _this$productCounts4[_i10]; 740 741 if (line.aantal === 0) { 742 continue; 743 } 744 745 var product = this.findProduct(line.arrangementsregel_id).product; 746 747 if (product.id !== parseInt(requiredProduct.vereist_product_id, 10)) { 748 continue; 749 } 750 751 var requiredAmount = this.requiredAmount(hasNow, requiredProduct); 752 return line.aantal >= requiredAmount; 753 } 754 755 return false; 756 } 757 }, { 758 key: "error", 759 value: function error(msg) { 760 this.loadingIndicatorHide(); 761 var bookingErrorsEl = this.findElement('#bookingErrors'); 762 763 if (bookingErrorsEl) { 764 bookingErrorsEl.parentNode.appendChild(this.findElement('.latestError')); 765 } 766 767 this.maybeAddLatestErrorElement(); 768 this.findElement('.latestError').innerHTML = "<strong>".concat(this.languageHelper.translate('ERR_GENERAL'), "</strong><p>").concat(msg, "</p>"); 769 } 770 }, { 771 key: "findElement", 772 value: function findElement(querystring) { 773 return this.element.querySelector(querystring); 774 } 775 }, { 776 key: "findElements", 777 value: function findElements(querystring) { 778 return this.element.querySelectorAll(querystring); 779 } 780 }, { 781 key: "findProduct", 782 value: function findProduct(packageLineID) { 783 return this.selectedPackage.regels.filter(function (line) { 784 return line.id === packageLineID; 785 })[0]; 786 } 787 }, { 788 key: "formatPrice", 789 value: function formatPrice(price) { 790 return this.languageHelper.formatPrice(price); 791 } 792 }, { 793 key: "getAvailableDays", 794 value: function getAvailableDays(packageID, begin, end) { 795 var _this11 = this; 796 797 var postData = { 798 arrangement_id: packageID, 799 begin: RecrasDateHelper.datePartOnly(begin), 800 eind: RecrasDateHelper.datePartOnly(end), 801 producten: this.productCountsNoBookingSize() 802 }; 803 804 if (this.shouldShowBookingSize(this.selectedPackage)) { 805 postData.boekingsgrootte = this.bookingSize(); 806 } 807 808 return this.postJson('onlineboeking/beschikbaredagen', postData).then(function (json) { 809 _this11.availableDays = _this11.availableDays.concat(json); 810 return _this11.availableDays; 811 }); 812 } 813 }, { 814 key: "getAvailableTimes", 815 value: function getAvailableTimes(packageID, date) { 816 var _this12 = this; 817 818 return this.postJson('onlineboeking/beschikbaretijden', { 819 arrangement_id: packageID, 820 datum: RecrasDateHelper.datePartOnly(date), 821 producten: this.productCounts() 822 }).then(function (json) { 823 _this12.availableTimes = json; 824 return _this12.availableTimes; 825 }); 826 } 827 }, { 828 key: "getContactForm", 829 value: function getContactForm(pack) { 830 var _this13 = this; 831 832 this.options.setOption('form_id', pack.onlineboeking_contactformulier_id); 833 var contactForm = new RecrasContactForm(this.options); 834 return contactForm.getContactFormFields().then(function () { 835 _this13.contactForm = contactForm; 836 return contactForm; 837 }); 838 } 839 }, { 840 key: "getDiscountPrice", 841 value: function getDiscountPrice(discount) { 842 if (!discount) { 843 return 0; 844 } 845 846 return discount.percentage / 100 * this.getSubTotal() * -1; 847 } 848 }, { 849 key: "getLinesBookingSize", 850 value: function getLinesBookingSize(pack) { 851 return pack.regels.filter(function (line) { 852 return line.onlineboeking_aantalbepalingsmethode === 'boekingsgrootte'; 853 }); 854 } 855 }, {
856 key: "getLinesNoBookingSize", 857 value: function getLinesNoBookingSize(pack) { 858 return pack.regels.filter(function (line) { 859 return line.onlineboeking_aantalbepalingsmethode !== 'boekingsgrootte'; 860 }); 861 } 862 }, { 863 key: "getPackages", 864 value: function getPackages() { 865 var _this14 = this; 866 867 return this.fetchJson(this.options.getApiBase() + 'arrangementen').then(function (json) { 868 _this14.packages = json; 869 return _this14.packages; 870 }); 871 } 872 }, { 873 key: "getProductByID", 874 value: function getProductByID(id) { 875 var products = this.selectedPackage.regels.map(function (r) { 876 return r.product; 877 }); 878 return products.filter(function (p) { 879 return p.id === id; 880 })[0]; 881 } 882 }, { 883 key: "getSubTotal", 884 value: function getSubTotal() { 885 var _this15 = this; 886 887 var total = 0; 888 this.productCounts().forEach(function (line) { 889 var product = _this15.findProduct(line.arrangementsregel_id).product; 890 891 var aantal = line.aantal; 892 893 if (isNaN(aantal)) { 894 aantal = 0; 895 } 896 897 total += aantal * parseFloat(product.verkoop); 898 }); 899 return total; 900 } 901 }, { 902 key: "getSetting", 903 value: function getSetting(settingName) { 904 return this.fetchJson(this.options.getApiBase() + 'instellingen/' + settingName); 905 } 906 }, { 907 key: "getTexts", 908 value: function getTexts() { 909 var settings = ['maximum_aantal_online_boeking_overschreden', 'online_boeking_betaalkeuze', 'online_boeking_betaalkeuze_achteraf_titel', 'online_boeking_betaalkeuze_ideal_titel', 'online_boeking_step0_text_pre', 'online_boeking_step0_text_post', 'online_boeking_step1_text_pre', 'online_boeking_step1_text_post', 'online_boeking_step3_text_post']; 910 var promises = []; 911 912 for (var _i12 = 0; _i12 < settings.length; _i12++) { 913 var setting = settings[_i12]; 914 promises.push(this.getSetting(setting)); 915 } 916 917 return Promise.all(promises).then(function (settings) { 918 var texts = {}; 919 settings.forEach(function (setting) { 920 texts[setting.slug] = setting.waarde; 921 }); 922 return texts; 923 }); 924 } 925 }, { 926 key: "getTotalPrice", 927 value: function getTotalPrice() { 928 var total = this.getSubTotal(); 929 total += this.getDiscountPrice(this.discount); 930 total += this.getVouchersPrice(); 931 return total; 932 } 933 }, { 934 key: "getVouchersPrice", 935 value: function getVouchersPrice() { 936 var voucherPrice = 0; 937 938 _objectValues(this.appliedVouchers).forEach(function (voucher) { 939 _objectValues(voucher).forEach(function (line) { 940 voucherPrice -= line.aantal * line.prijs_per_stuk; 941 }); 942 }); 943 944 return voucherPrice; 945 } 946 }, { 947 key: "loadingIndicatorHide", 948 value: function loadingIndicatorHide() { 949 _toConsumableArray(document.querySelectorAll('.recrasLoadingIndicator')).forEach(function (el) { 950 el.parentNode.removeChild(el); 951 }); 952 } 953 }, { 954 key: "loadingIndicatorShow", 955 value: function loadingIndicatorShow(afterEl) { 956 if (!afterEl) { 957 return; 958 } 959 960 afterEl.insertAdjacentHTML('beforeend', "<span class=\"recrasLoadingIndicator\">".concat(this.languageHelper.translate('LOADING'), "</span>")); 961 } 962 }, { 963 key: "maybeAddLatestErrorElement", 964 value: function maybeAddLatestErrorElement() { 965 var errorEl = this.findElement('.latestError'); 966 967 if (!errorEl) { 968 this.appendHtml("<div class=\"latestError\"></div>"); 969 } 970 } 971 }, {
972 key: "maybeDisableBookButton", 973 value: function maybeDisableBookButton() { 974 var _this16 = this; 975 976 var button = this.findElement('.bookPackage'); 977 978 if (!button) { 979 return false; 980 } 981 982 var bookingDisabledReasons = []; 983 984 if (this.requiresProduct) { 985 bookingDisabledReasons.push('BOOKING_DISABLED_REQUIRED_PRODUCT'); 986 } 987 988 if (!this.amountsValid(this.selectedPackage)) { 989 bookingDisabledReasons.push('BOOKING_DISABLED_AMOUNTS_INVALID'); 990 } 991 992 if (!this.selectedDate) { 993 bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_DATE'); 994 } 995 996 if (!this.selectedTime) { 997 bookingDisabledReasons.push('BOOKING_DISABLED_INVALID_TIME'); 998 } 999 1000 if (!this.contactFormValid()) { 1001 bookingDisabledReasons.push('BOOKING_DISABLED_CONTACT_FORM_INVALID'); 1002 } 1003 1004 var agreeEl = this.findElement('#recrasAgreeToAttachments'); 1005 1006 if (agreeEl && !agreeEl.checked) { 1007 bookingDisabledReasons.push('BOOKING_DISABLED_AGREEMENT'); 1008 } 1009 1010 if (bookingDisabledReasons.length > 0) { 1011 var reasonsList = bookingDisabledReasons.map(function (reason) { 1012 return _this16.languageHelper.translate(reason); 1013 }).join('<li>'); 1014 this.findElement('#bookingErrors').innerHTML = "<ul><li>".concat(reasonsList, "</ul>"); 1015 button.setAttribute('disabled', 'disabled'); 1016 } else { 1017 this.findElement('#bookingErrors').innerHTML = ''; 1018 button.removeAttribute('disabled'); 1019 } 1020 } 1021 }, { 1022 key: "nextSectionActive", 1023 value: function nextSectionActive(completedQuery, activeQuery) { 1024 if (completedQuery && this.findElement(completedQuery)) { 1025 this.findElement(completedQuery).classList.add('recras-completed'); 1026 this.findElement(completedQuery).classList.remove('recras-active'); 1027 } //TODO: remove active from all sections? Test with invalid amount 1028 1029 1030 if (activeQuery && this.findElement(activeQuery)) { 1031 this.findElement(activeQuery).classList.add('recras-active'); 1032 } 1033 } 1034 }, { 1035 key: "normaliseDate", 1036 value: function normaliseDate(date, packageStart, bookingStart) { 1037 var diffSeconds = (date - packageStart) / 1000; 1038 var tempDate = new Date(bookingStart.getTime()); 1039 return new Date(tempDate.setSeconds(tempDate.getSeconds() + diffSeconds)); 1040 } 1041 }, { 1042 key: "paymentMethods", 1043 value: function paymentMethods(pack) { 1044 var methods = []; 1045 1046 if (pack.mag_online_geboekt_worden_direct_betalen) { 1047 methods.push(this.PAYMENT_DIRECT); 1048 } 1049 1050 if (pack.mag_online_geboekt_worden_achteraf_betalen) { 1051 methods.push(this.PAYMENT_AFTERWARDS); 1052 } 1053 1054 return methods; 1055 } 1056 }, { 1057 key: "preFillAmounts", 1058 value: function preFillAmounts(amounts) { 1059 var _this17 = this; 1060 1061 _objectEntries(amounts).forEach(function (idAmount) { 1062 var el; 1063 1064 if (idAmount[0] === 'bookingsize') { 1065 el = _this17.findElement('#bookingsize'); 1066 } else { 1067 el = _this17.findElement("[data-package-id=\"".concat(idAmount[0], "\"]")); 1068 } 1069 1070 if (el) { 1071 el.value = idAmount[1]; 1072 1073 _this17.updateProductPrice(el); 1074 } 1075 }); 1076 1077 this.updateProductAmounts(); 1078 } 1079 }, { 1080 key: "previewTimes", 1081 value: function previewTimes() { 1082 var _this18 = this; 1083 1084 _toConsumableArray(this.findElements('.time-preview')).forEach(function (el) { 1085 el.parentNode.removeChild(el); 1086 }); 1087 1088 if (this.selectedTime) { 1089 var linesWithTime = this.selectedPackage.regels.filter(function (line) { 1090 return !!line.begin; 1091 }); 1092 var linesBegin = linesWithTime.map(function (line) { 1093 return new Date(line.begin); 1094 }); 1095 var packageStart = new Date(Math.min.apply(Math, _toConsumableArray(linesBegin))); // Math.min transforms dates to timestamps 1096 1097 var linesNoBookingSize = this.getLinesNoBookingSize(this.selectedPackage); 1098 linesNoBookingSize.forEach(function (line, idx) { 1099 if (line.begin !== null || line.eind !== null) { 1100 var normalisedStart = _this18.normaliseDate(new Date(line.begin), packageStart, _this18.selectedDate); 1101 1102 var normalisedEnd = _this18.normaliseDate(new Date(line.eind), packageStart, _this18.selectedDate); 1103 1104 _this18.findElement("label[for=\"packageline".concat(idx, "\"]")).insertAdjacentHTML('afterbegin', "<span class=\"time-preview\">".concat(RecrasDateHelper.timePartOnly(normalisedStart), " \u2013 ").concat(RecrasDateHelper.timePartOnly(normalisedEnd), "</span>")); 1105 } 1106 }); 1107 } 1108 } 1109 }, {
1110 key: "productCountsBookingSize", 1111 value: function productCountsBookingSize() { 1112 var _this19 = this; 1113 1114 return this.getLinesBookingSize(this.selectedPackage).map(function (line) { 1115 return { 1116 aantal: _this19.bookingSize(), 1117 arrangementsregel_id: line.id 1118 }; 1119 }); 1120 } 1121 }, { 1122 key: "productCountsNoBookingSize", 1123 value: function productCountsNoBookingSize() { 1124 return _toConsumableArray(this.findElements('[id^="packageline"]')).map(function (line) { 1125 return { 1126 aantal: isNaN(parseInt(line.value)) ? 0 : parseInt(line.value), 1127 arrangementsregel_id: parseInt(line.dataset.packageId, 10) 1128 }; 1129 }); 1130 } 1131 }, { 1132 key: "productCounts", 1133 value: function productCounts() { 1134 var counts = []; 1135 counts = counts.concat(this.productCountsNoBookingSize()); 1136 counts = counts.concat(this.productCountsBookingSize()); 1137 return counts; 1138 } 1139 }, { 1140 key: "removeWarnings", 1141 value: function removeWarnings() { 1142 _toConsumableArray(this.findElements('.booking-error:not(#bookingErrors)')).forEach(function (el) { 1143 el.parentNode.removeChild(el); 1144 }); 1145 1146 _toConsumableArray(this.findElements('.minimum-amount')).forEach(function (el) { 1147 el.parentNode.removeChild(el); 1148 }); 1149 1150 _toConsumableArray(this.findElements('.maximum-amount')).forEach(function (el) { 1151 el.parentNode.removeChild(el); 1152 }); 1153 1154 _toConsumableArray(this.findElements('.recras-input-invalid')).forEach(function (el) { 1155 el.classList.remove('recras-input-invalid'); 1156 }); 1157 1158 _toConsumableArray(this.findElements('.recras-success')).forEach(function (el) { 1159 el.parentNode.removeChild(el); 1160 }); 1161 } 1162 /** 1163 * requiredAmount calculates the amount N needed of Y in the sentence 'product X requires N times product Y' 1164 * 1165 * @param {number} hasNow The amount of product X selected 1166 * @param {object} requiredProduct 1167 * @param {number} requiredProduct.aantal The base amount of Y required 1168 * @param {number} requiredProduct.per_x_aantal The quantum of X that will require product Y 1169 * @param {"boven"|"beneden"} requiredProduct.afronding Indication of how hasNow / per_x_aantal should be rounded ("boven" will round up, "beneden" will round down) 1170 * @return {number} The amount of product Y needed 1171 */ 1172 1173 }, { 1174 key: "requiredAmount", 1175 value: function requiredAmount(hasNow, requiredProduct) { 1176 var requiredFraction = hasNow / requiredProduct.per_x_aantal; 1177 1178 if (requiredProduct.afronding === 'boven') { 1179 requiredFraction = Math.ceil(requiredFraction); 1180 } else { 1181 requiredFraction = Math.floor(requiredFraction); 1182 } 1183 1184 return requiredProduct.aantal * requiredFraction; 1185 } 1186 }, { 1187 key: "resetForm", 1188 value: function resetForm() { 1189 this.changePackage(null); 1190 } 1191 }, { 1192 key: "selectSingleTime", 1193 value: function selectSingleTime() { 1194 if (this.findElements('#recras-onlinebooking-time option[value]').length !== 1) { 1195 return; 1196 } 1197 1198 this.findElement('#recras-onlinebooking-time option[value]').selected = true; 1199 this.findElement('#recras-onlinebooking-time').dispatchEvent(new Event('change')); 1200 } 1201 }, { 1202 key: "setDiscountStatus", 1203 value: function setDiscountStatus(statusText) { 1204 var isError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 1205 var statusEl = this.findElement('.discount-status'); 1206 1207 if (!statusEl) { 1208 this.element.querySelector('.recras-discounts').insertAdjacentHTML('beforeend', "<span class=\"discount-status\"></span>"); 1209 statusEl = this.findElement('.discount-status'); 1210 } 1211 1212 if (isError) { 1213 statusEl.classList.add('booking-error'); 1214 } else { 1215 statusEl.classList.remove('booking-error'); 1216 } 1217 1218 statusEl.innerHTML = statusText; 1219 } 1220 }, {
1221 key: "setHtml", 1222 value: function setHtml(msg) { 1223 this.element.innerHTML = msg; 1224 } 1225 }, { 1226 key: "showStandardAttachments", 1227 value: function showStandardAttachments() { 1228 if (!this.selectedPackage || !this.findElement('.standard-attachments')) { 1229 return true; 1230 } 1231 1232 var attachments = this.standardAttachments(this.selectedPackage); 1233 var attachmentHtml = ""; 1234 1235 if (Object.keys(attachments).length) { 1236 attachmentHtml += "<p><label><input type=\"checkbox\" id=\"recrasAgreeToAttachments\" required>".concat(this.languageHelper.translate('AGREE_ATTACHMENTS'), "</label></p>"); 1237 attachmentHtml += "<ul>"; 1238 1239 _objectValues(attachments).forEach(function (attachment) { 1240 attachmentHtml += "<li><a href=\"".concat(attachment.filename, "\" download target=\"_blank\">").concat(attachment.naam, "</a></li>"); 1241 }); 1242 1243 attachmentHtml += "</ul>"; 1244 } 1245 1246 this.findElement('.standard-attachments').innerHTML = attachmentHtml; 1247 var agreeEl = this.findElement('#recrasAgreeToAttachments'); 1248 1249 if (agreeEl) { 1250 agreeEl.addEventListener('change', this.maybeDisableBookButton.bind(this)); 1251 } 1252 } 1253 }, { 1254 key: "showTotalPrice", 1255 value: function showTotalPrice() { 1256 _toConsumableArray(this.findElements('.discountLine, .voucherLine, .priceWithDiscount')).forEach(function (el) { 1257 el.parentNode.removeChild(el); 1258 }); 1259 1260 var html = ""; 1261 1262 if (this.discount) { 1263 html += "<div class=\"discountLine\"><div>".concat(this.discount.naam, "</div><div>").concat(this.formatPrice(this.getDiscountPrice(this.discount)), "</div></div>"); 1264 } 1265 1266 if (Object.keys(this.appliedVouchers).length) { 1267 html += "<div class=\"voucherLine\"><div>".concat(this.languageHelper.translate('VOUCHERS_DISCOUNT'), "</div><div>").concat(this.formatPrice(this.getVouchersPrice()), "</div></div>"); 1268 } 1269 1270 if (this.discount || Object.keys(this.appliedVouchers).length) { 1271 html += "<div class=\"priceWithDiscount\"><div>".concat(this.languageHelper.translate('PRICE_TOTAL_WITH_DISCOUNT'), "</div><div>").concat(this.formatPrice(this.getTotalPrice()), "</div></div>"); 1272 } 1273 1274 var elementToInsertBefore = this.findElement('.recras-amountsform p:last-of-type'); 1275 1276 if (elementToInsertBefore) { 1277 elementToInsertBefore.insertAdjacentHTML('beforebegin', html); 1278 } 1279 1280 var subtotalEl = this.findElement('.priceSubtotal'); 1281 1282 if (subtotalEl) { 1283 subtotalEl.innerHTML = this.formatPrice(this.getSubTotal()); 1284 } 1285 } 1286 }, { 1287 key: "sortPackages", 1288 value: function sortPackages(packages) { 1289 // Packages from the API are sorted by internal name, not by display name 1290 // However, display name is not required so fallback to internal name 1291 return packages.sort(function (a, b) { 1292 var aName = a.weergavenaam || a.arrangement; 1293 var bName = b.weergavenaam || b.arrangement; 1294 1295 if (aName < bName) { 1296 return -1; 1297 } 1298 1299 if (aName > bName) { 1300 return 1; 1301 } 1302 1303 return 0; 1304 }); 1305 } 1306 }, { 1307 key: "shouldShowBookingSize", 1308 value: function shouldShowBookingSize(pack) { 1309 return this.bookingSizeLines(pack).length > 0; 1310 } 1311 }, { 1312 key: "showBookButton", 1313 value: function showBookButton() { 1314 var _this20 = this; 1315 1316 var promises = []; 1317 var paymentMethods = this.paymentMethods(this.selectedPackage); 1318 var paymentText = ''; 1319 var textPostBooking = ''; 1320 1321 if (paymentMethods.indexOf(this.PAYMENT_DIRECT) > -1 && paymentMethods.indexOf(this.PAYMENT_AFTERWARDS) > -1) { 1322 // Let user decide how to pay 1323 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze, this.selectedPackage ? this.selectedPackage.id : null)); 1324 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze_ideal_titel, this.selectedPackage ? this.selectedPackage.id : null)); 1325 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_betaalkeuze_achteraf_titel, this.selectedPackage ? this.selectedPackage.id : null)); 1326 Promise.all(promises).then(function (msgs) { 1327 paymentText = "<p>".concat(msgs[0], "</p>"); 1328 paymentText += "<ul>\n <li><label><input type=\"radio\" name=\"paymentMethod\" checked value=\"".concat(_this20.PAYMENT_DIRECT, "\"> ").concat(msgs[1], "</label>\n <li><label><input type=\"radio\" name=\"paymentMethod\" value=\"").concat(_this20.PAYMENT_AFTERWARDS, "\"> ").concat(msgs[2], "</label>\n </ul>"); 1329 }); 1330 } else { 1331 // One fixed choice
1332 promises.push(Promise.resolve('')); 1333 } 1334 1335 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step3_text_post, this.selectedPackage ? this.selectedPackage.id : null).then(function (msg) { 1336 textPostBooking = msg; 1337 })); 1338 Promise.all(promises).then(function () { 1339 var html = "<div class=\"recras-finalise\">\n <p>".concat(textPostBooking, "</p>\n <div class=\"standard-attachments\"></div>\n ").concat(paymentText, "\n <button type=\"submit\" class=\"bookPackage\" disabled>").concat(_this20.languageHelper.translate('BUTTON_BOOK_NOW'), "</button>\n <div class=\"booking-error\" id=\"bookingErrors\"></div>\n </div>"); 1340 1341 _this20.appendHtml(html); 1342 1343 _this20.findElement('.bookPackage').addEventListener('click', _this20.submitBooking.bind(_this20)); 1344 1345 _this20.maybeDisableBookButton(); 1346 1347 _this20.updateProductAmounts(); 1348 }); 1349 } 1350 }, { 1351 key: "showDiscountFields", 1352 value: function showDiscountFields() { 1353 var _this21 = this; 1354 1355 var existingEl = this.findElement('.recras-discounts'); 1356 1357 if (existingEl) { 1358 existingEl.parentNode.removeChild(existingEl); 1359 } 1360 1361 var html = "\n <form class=\"recras-discounts\">\n <div>\n <label for=\"discountcode\">".concat(this.languageHelper.translate('DISCOUNT_TITLE'), "</label>\n <input type=\"text\" id=\"discountcode\" class=\"discountcode\" maxlength=\"50\" disabled>\n </div>\n <button type=\"submit\" class=\"button-secondary\">").concat(this.languageHelper.translate('DISCOUNT_CHECK'), "</button>\n </form>\n "); 1362 this.findElement('.recras-datetime').insertAdjacentHTML('afterend', html); 1363 this.findElement('.recras-discounts').addEventListener('submit', function (e) { 1364 e.preventDefault(); 1365 1366 _this21.checkDiscountAndVoucher(); 1367 1368 return false; 1369 }); 1370 } 1371 }, { 1372 key: "showContactForm", 1373 value: function showContactForm(pack) { 1374 var _this22 = this; 1375 1376 this.loadingIndicatorShow(this.findElement('.recras-datetime')); 1377 this.getContactForm(pack).then(function (form) { 1378 return form.generateForm(); 1379 }).then(function (html) { 1380 _this22.appendHtml(html); 1381 1382 _this22.loadingIndicatorHide(); 1383 1384 _this22.showBookButton(); 1385 1386 _this22.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_CONTACT_FORM_SHOWN); 1387 1388 _toConsumableArray(_this22.findElements('[name^="contactformulier"]')).forEach(function (el) { 1389 el.addEventListener('input', _this22.maybeDisableBookButton.bind(_this22)); 1390 el.addEventListener('input', function () { 1391 if (_this22.contactFormValid()) { 1392 _this22.nextSectionActive('.recras-contactform', '.recras-finalise'); 1393 } 1394 }); 1395 }); 1396 }); 1397 } 1398 }, { 1399 key: "maybeFillTime", 1400 value: function maybeFillTime(times) { 1401 times = times.map(function (time) { 1402 return RecrasDateHelper.timePartOnly(new Date(time)); 1403 }); 1404 this.showTimes(times); 1405 this.loadingIndicatorHide(); 1406 1407 if (!this.prefilledTime) { 1408 this.selectSingleTime(); 1409 return; 1410 } 1411 1412 if (times.includes(this.prefilledTime)) { 1413 this.selectTime(this.prefilledTime); 1414 this.selectedDate = RecrasDateHelper.setTimeForDate(this.selectedDate, this.selectedTime); 1415 1416 if (this.options.getPreviewTimes() === true) { 1417 this.previewTimes(); 1418 } 1419 1420 return; 1421 } 1422 1423 this.toggleTimeField('show'); 1424 } 1425 }, {
1426 key: "calendarOnDateSelect", 1427 value: function calendarOnDateSelect(date, packageId) { 1428 var _this23 = this; 1429 1430 this.removeWarnings(); 1431 this.loadingIndicatorShow(this.findElement('label[for="recras-onlinebooking-time"]')); 1432 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_DATE_SELECTED, RecrasDateHelper.datePartOnly(date)); 1433 this.selectedDate = date; 1434 1435 if (this.hasAtLeastOneProduct(this.selectedPackage)) { 1436 this.getAvailableTimes(packageId, date).then(function (times) { 1437 return _this23.maybeFillTime(times); 1438 }); 1439 } 1440 1441 if (this.discount && this.discount.code) { 1442 this.recheckDiscountCode(); 1443 } 1444 1445 this.findElement('#discountcode').removeAttribute('disabled'); 1446 this.maybeDisableBookButton(); 1447 } 1448 }, { 1449 key: "calendarOnDraw", 1450 value: function calendarOnDraw(pika, packageId) { 1451 var lastMonthYear = pika.calendars[pika.calendars.length - 1]; 1452 var lastDay = new Date(lastMonthYear.year, lastMonthYear.month, 31); 1453 var lastAvailableDay = this.availableDays.reduce(function (acc, curVal) { 1454 return curVal > acc ? curVal : acc; 1455 }, ''); 1456 1457 if (!lastAvailableDay) { 1458 lastAvailableDay = new Date(); 1459 } else { 1460 lastAvailableDay = new Date(lastAvailableDay); 1461 } 1462 1463 if (lastAvailableDay > lastDay) { 1464 return; 1465 } 1466 1467 var newEndDate = RecrasDateHelper.clone(lastAvailableDay); 1468 newEndDate.setFullYear(lastMonthYear.year); 1469 newEndDate.setMonth(lastMonthYear.month + 3); 1470 newEndDate.setDate(0); // Set to 0th day of the month = last day of previous month 1471 1472 this.getAvailableDays(packageId, lastAvailableDay, newEndDate); 1473 } 1474 }, { 1475 key: "addDateTimeSelectionHtml", 1476 value: function addDateTimeSelectionHtml() { 1477 var today = RecrasDateHelper.datePartOnly(new Date()); 1478 var html = "<form class=\"recras-datetime\">\n <label for=\"recras-onlinebooking-date\">\n ".concat(this.languageHelper.translate('DATE'), "\n </label>\n <input type=\"text\" id=\"recras-onlinebooking-date\" class=\"recras-onlinebooking-date\" min=\"").concat(today, "\" disabled autocomplete=\"off\">\n <label for=\"recras-onlinebooking-time\">\n ").concat(this.languageHelper.translate('TIME'), "\n </label>\n <select id=\"recras-onlinebooking-time\" class=\"recras-onlinebooking-time\" disabled autocomplete=\"off\"></select>\n </form>"); 1479 this.appendHtml(html); 1480 } 1481 }, { 1482 key: "selectTime", 1483 value: function selectTime(time) { 1484 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_TIME_SELECTED); 1485 this.selectedTime = time; 1486 this.maybeDisableBookButton(); 1487 } 1488 }, { 1489 key: "showDateTimeSelection", 1490 value: function showDateTimeSelection(pack) { 1491 var _this24 = this; 1492 1493 this.addDateTimeSelectionHtml(); 1494 this.showDiscountFields(); 1495 1496 if (this.prefilledDate) { 1497 this.toggleDateField('hide'); 1498 this.calendarOnDateSelect(this.prefilledDate, pack.id); 1499 } 1500 1501 if (this.prefilledTime) { 1502 this.toggleTimeField('hide'); 1503 } 1504 1505 if (this.prefilledDate && this.prefilledTime) { 1506 this.findElement('.recras-datetime').classList.add('recrasHidden'); 1507 } 1508 1509 if (this.options.getPreFilledAmounts()) { 1510 this.preFillAmounts(this.options.getPreFilledAmounts()); 1511 } 1512 1513 var pikadayOptions = _extends(RecrasCalendarHelper.defaultOptions(), { 1514 disableDayFn: function disableDayFn(day) { 1515 var dateFmt = RecrasDateHelper.datePartOnly(day); 1516 return _this24.availableDays.indexOf(dateFmt) === -1; 1517 },
1518 field: this.findElement('.recras-onlinebooking-date'), 1519 i18n: RecrasCalendarHelper.i18n(this.languageHelper), 1520 onDraw: function onDraw(pika) { 1521 return _this24.calendarOnDraw(pika, pack.id); 1522 }, 1523 onSelect: function onSelect(date) { 1524 return _this24.calendarOnDateSelect(date, pack.id); 1525 }, 1526 parse: RecrasDateHelper.parseMDY 1527 }); 1528 1529 this.datePicker = new Pikaday(pikadayOptions); 1530 this.findElement('.recras-onlinebooking-time').addEventListener('change', function () { 1531 _this24.selectTime(_this24.findElement('.recras-onlinebooking-time').value); 1532 1533 _this24.nextSectionActive('.recras-datetime', '.recras-discounts'); 1534 1535 _this24.nextSectionActive(null, '.recras-contactform'); 1536 1537 _this24.selectedDate = RecrasDateHelper.setTimeForDate(_this24.selectedDate, _this24.selectedTime); 1538 1539 if (_this24.options.getPreviewTimes() === true) { 1540 _this24.previewTimes(); 1541 } 1542 1543 _this24.maybeDisableBookButton(); 1544 }); 1545 } 1546 }, { 1547 key: "showPackages", 1548 value: function showPackages(packages) { 1549 var _this25 = this; 1550 1551 packages = packages.filter(function (p) { 1552 return p.mag_online; 1553 }); 1554 var packagesSorted = this.sortPackages(packages); 1555 var packageOptions = packagesSorted.map(function (pack) { 1556 return "<option value=\"".concat(pack.id, "\">").concat(pack.weergavenaam || pack.arrangement); 1557 }); 1558 var html = '<select class="recras-package-selection"><option>' + packageOptions.join('') + '</select>'; 1559 var promises = []; 1560 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step0_text_pre, this.selectedPackage ? this.selectedPackage.id : null)); 1561 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step0_text_post, this.selectedPackage ? this.selectedPackage.id : null)); 1562 return Promise.all(promises).then(function (msgs) { 1563 _this25.appendHtml("<div class=\"recras-package-select recras-active\"><p>".concat(msgs[0], "</p>").concat(html, "<p>\n").concat(msgs[1], "</p></div>")); 1564 1565 _this25.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_PACKAGES_SHOWN); 1566 1567 var packageSelectEl = _this25.findElement('.recras-package-selection'); 1568 1569 packageSelectEl.addEventListener('change', function () { 1570 var selectedPackageId = parseInt(packageSelectEl.value, 10); 1571 1572 _this25.changePackage(selectedPackageId); 1573 }); 1574 }); 1575 } 1576 }, { 1577 key: "showProducts", 1578 value: function showProducts(pack) { 1579 var _this26 = this; 1580 1581 var promises = []; 1582 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step1_text_pre, this.selectedPackage ? this.selectedPackage.id : null)); 1583 promises.push(this.languageHelper.filterTags(this.texts.online_boeking_step1_text_post, this.selectedPackage ? this.selectedPackage.id : null)); 1584 return Promise.all(promises).then(function (msgs) { 1585 var html = '<form class="recras-amountsform" onsubmit="return false">'; 1586 html += "<p>".concat(msgs[0], "</p>"); 1587 html += "<div class=\"recras-heading\">\n <div> </div>\n <div>".concat(_this26.languageHelper.translate('HEADING_QUANTITY'), "</div>\n <div class=\"recras-price\">").concat(_this26.languageHelper.translate('HEADING_PRICE'), "</div>\n </div>"); 1588 1589 if (_this26.shouldShowBookingSize(pack)) { 1590 html += "<div>"; 1591 html += "<div><label for=\"bookingsize\">".concat(pack.weergavenaam || pack.arrangement, "</label></div>"); 1592 html += "<input type=\"number\" id=\"bookingsize\" class=\"bookingsize\" min=\"".concat(_this26.bookingSizeMinimum(pack), "\" max=\"").concat(_this26.bookingSizeMaximum(pack), "\" placeholder=\"0\" data-price=\"").concat(_this26.bookingSizePrice(pack), "\">"); 1593 html += "<div class=\"recras-price recrasUnitPrice\">".concat(_this26.formatPrice(_this26.bookingSizePrice(pack)), "</div>"); 1594 html += "</div>"; 1595 } 1596 1597 var linesNoBookingSize = _this26.getLinesNoBookingSize(pack); 1598 1599 linesNoBookingSize.forEach(function (line, idx) { 1600 html += '<div><div>'; 1601 html += "<label for=\"packageline".concat(idx, "\">").concat(line.beschrijving_templated, "</label>"); 1602 var maxAttr = line.max ? "max=\"".concat(line.max, "\"") : ''; 1603 html += "</div><input id=\"packageline".concat(idx, "\" type=\"number\" min=\"0\" ").concat(maxAttr, " placeholder=\"0\" data-package-id=\"").concat(line.id, "\" data-price=\"").concat(line.product.verkoop, "\">"); 1604 html += "<div class=\"recras-price recrasUnitPrice\">".concat(_this26.formatPrice(line.product.verkoop), "</div>"); 1605 html += '</div>'; 1606 }); 1607 html += "<div class=\"priceWithoutDiscount\">\n <div>".concat(_this26.languageHelper.translate('PRICE_TOTAL'), "</div>\n <div></div>\n <div class=\"priceSubtotal\"></div>\n </div>"); 1608 html += "<p>".concat(msgs[1], "</p>"); 1609 html += '</form>'; 1610 1611 _this26.appendHtml(html); 1612 1613 _toConsumableArray(_this26.findElements('[id^="packageline"], .bookingsize')).forEac
1613h(function (el) { 1614 el.addEventListener('input', _this26.updateProductAmounts.bind(_this26)); 1615 el.addEventListener('input', _this26.updateProductPrice.bind(_this26, el)); 1616 }); 1617 }); 1618 } 1619 }, { 1620 key: "showTimes", 1621 value: function showTimes(times) { 1622 var html = "<option>"; 1623 times.forEach(function (time) { 1624 html += "<option value=\"".concat(time, "\">").concat(time); 1625 }); 1626 this.findElement('.recras-onlinebooking-time').innerHTML = html; 1627 this.findElement('.recras-onlinebooking-time').removeAttribute('disabled'); 1628 1629 if (times.length === 0) { 1630 this.findElement('.recras-datetime').insertAdjacentHTML('afterend', "<div class=\"booking-error\">".concat(this.languageHelper.translate('ERR_NO_TIMES_FOR_DATE'), "</div>")); 1631 } 1632 } 1633 }, { 1634 key: "clearTimes", 1635 value: function clearTimes() { 1636 this.findElement('.recras-onlinebooking-time').innerHTML = ''; 1637 this.findElement('.recras-onlinebooking-time').setAttribute('disabled', 'disabled'); 1638 } 1639 }, { 1640 key: "standardAttachments", 1641 value: function standardAttachments() { 1642 var _this27 = this; 1643 1644 var attachments = {}; 1645 1646 if (!this.selectedPackage.onlineboeking_standaardbijlagen_meesturen) { 1647 return attachments; 1648 } 1649 1650 this.productCounts().forEach(function (line) { 1651 if (line.aantal > 0) { 1652 var product = _this27.findProduct(line.arrangementsregel_id).product; 1653 1654 if (product.standaardbijlagen) { 1655 product.standaardbijlagen.forEach(function (attachment) { 1656 attachments[attachment.id] = attachment; 1657 }); 1658 } 1659 } 1660 }); 1661 return attachments; 1662 } 1663 }, { 1664 key: "formatGA4Items", 1665 value: function formatGA4Items() { 1666 var _this28 = this; 1667 1668 var items = []; 1669 1670 if (this.bookingSize() > 0) { 1671 var pck = this.selectedPackage; 1672 items.push({ 1673 item_name: pck.weergavenaam || pck.arrangement, 1674 price: this.bookingSizePrice(pck), 1675 quantity: this.bookingSize() 1676 }); 1677 } 1678 1679 var linesNoBookingSize = this.getLinesNoBookingSize(this.selectedPackage); 1680 linesNoBookingSize = linesNoBookingSize.filter(function (line) { 1681 var lineEl = _this28.findElement("[data-package-id=\"".concat(line.id, "\"]")); 1682 1683 if (!lineEl) { 1684 return false; 1685 } 1686 1687 if (isNaN(parseInt(lineEl.value))) { 1688 return false; 1689 } 1690 1691 return parseInt(lineEl.value) > 0; 1692 }); 1693 linesNoBookingSize = linesNoBookingSize.map(function (line) { 1694 var lineEl = _this28.findElement("[data-package-id=\"".concat(line.id, "\"]")); 1695 1696 return { 1697 item_name: line.beschrijving_templated, 1698 price: line.product.verkoop, 1699 quantity: parseInt(lineEl.value) 1700 }; 1701 }); 1702 items.push.apply(items, _toConsumableArray(linesNoBookingSize)); 1703 return items; 1704 } 1705 }, { 1706 key: "submitBooking", 1707 value: function submitBooking() { 1708 var _this29 = this; 1709 1710 var productCounts = this.productCounts().map(function (line) { 1711 return line.aantal; 1712 }); 1713 var productSum = productCounts.reduce(function (a, b) { 1714 return a + b; 1715 }, 0); 1716 1717 if (this.bookingSize() === 0 && productSum === 0) { 1718 this.error(this.languageHelper.translate('NO_PRODUCTS')); 1719 return false; 1720 } 1721 1722 var status = this.contactForm.checkRequiredCheckboxes(); 1723 1724 if (!status) { 1725 return false;
1726 } 1727 1728 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_BOOKING_SUBMITTED, this.selectedPackage.arrangement, Math.round(this.getTotalPrice())); 1729 var paymentMethod = this.paymentMethods(this.selectedPackage)[0]; 1730 var paymentMethodEl = this.findElement('[name="paymentMethod"]:checked'); 1731 1732 if (paymentMethodEl && this.validPaymentMethod(this.selectedPackage, paymentMethodEl.value)) { 1733 paymentMethod = paymentMethodEl.value; 1734 } 1735 1736 this.loadingIndicatorHide(); 1737 this.loadingIndicatorShow(this.findElement('.bookPackage')); 1738 var elem; 1739 1740 if (null !== (elem = this.findElement('.bookPackage'))) { 1741 elem.setAttribute('disabled', 'disabled'); 1742 } 1743 1744 var vouchers = Object.keys(this.appliedVouchers).length > 0 ? Object.keys(this.appliedVouchers) : null; 1745 var bookingParams = { 1746 arrangement_id: this.selectedPackage.id, 1747 begin: this.selectedDate, 1748 betaalmethode: paymentMethod, 1749 contactformulier: this.contactForm.generateJson(), 1750 kortingscode: this.discount && this.discount.code || null, 1751 producten: this.productCounts(), 1752 status: null, 1753 stuur_bevestiging_email: true, 1754 vouchers: vouchers 1755 }; 1756 1757 if (this.shouldShowBookingSize(this.selectedPackage)) { 1758 bookingParams.boekingsgrootte = this.bookingSize(); 1759 } 1760 1761 if (this.options.getRedirectUrl()) { 1762 bookingParams.redirect_url = this.options.getRedirectUrl(); 1763 } 1764 1765 return this.postJson('onlineboeking/reserveer', bookingParams).then(function (json) { 1766 if (json.payment_url) { 1767 _this29.eventHelper.sendEvent(RecrasEventHelper.PREFIX_BOOKING, RecrasEventHelper.EVENT_BOOKING_REDIRECT_PAYMENT, null, Math.round(_this29.getTotalPrice()), { 1768 currency: _this29.languageHelper.currency, 1769 value: _this29.getTotalPrice(), 1770 items: _this29.formatGA4Items() 1771 }); 1772 1773 window.top.location.href = json.payment_url; 1774 } else if (json.redirect) { 1775 window.top.location.href = json.redirect; 1776 } else if (json.message && json.status) { 1777 _this29.findElement('.recras-amountsform').reset(); 1778 1779 _this29.findElement('.recras-datetime').reset(); 1780 1781 _this29.findElement('.recras-contactform').reset(); 1782 1783 _this29.element.scrollIntoView({ 1784 behavior: 'smooth' 1785 }); 1786 1787 _this29.element.insertAdjacentHTML('afterbegin', "<p class=\"recras-success\">".concat(json.message, "</p>")); 1788 } else { 1789 console.log(json); 1790 } 1791 1792 _this29.loadingIndicatorHide(); 1793 1794 _this29.findElement('.bookPackage').removeAttribute('disabled'); 1795 }); 1796 } 1797 }, { 1798 key: "toggleDateField", 1799 value: function toggleDateField(showHide) { 1800 var dateEl = this.findElement('#recras-onlinebooking-date'); 1801 var labelEl = this.findElement('[for="recras-onlinebooking-date"]'); 1802 1803 if (showHide === 'hide') { 1804 dateEl.classList.add('recrasHidden'); 1805 labelEl.classList.add('recrasHidden'); 1806 } else { 1807 dateEl.classList.remove('recrasHidden'); 1808 labelEl.classList.remove('recrasHidden'); 1809 this.findElement('.recras-datetime').classList.remove('recrasHidden'); 1810 } 1811 } 1812 }, { 1813 key: "toggleTimeField", 1814 value: function toggleTimeField(showHide) { 1815 var timeEl = this.findElement('#recras-onlinebooking-time'); 1816 var labelEl = this.findElement('[for="recras-onlinebooking-time"]'); 1817 1818 if (showHide === 'hide') { 1819 timeEl.classList.add('recrasHidden'); 1820 labelEl.classList.add('recrasHidden'); 1821 } else { 1822 timeEl.classList.remove('recrasHidden'); 1823 labelEl.classList.remove('recrasHidden');
1824 this.findElement('.recras-datetime').classList.remove('recrasHidden'); 1825 } 1826 } 1827 }, { 1828 key: "updateProductAmounts", 1829 value: function updateProductAmounts() { 1830 var _this30 = this; 1831 1832 this.loadingIndicatorHide(); 1833 this.availableDays = []; 1834 this.removeWarnings(); 1835 this.checkDependencies(); 1836 this.checkMinMaxAmounts(); 1837 var maxPromise = this.checkMaximumForPackage(); 1838 this.checkBookingSize(this.selectedPackage); 1839 this.recheckVouchers().then(function () { 1840 _this30.showTotalPrice(); 1841 }); 1842 this.showStandardAttachments(); 1843 var datePickerEl = this.findElement('.recras-onlinebooking-date'); 1844 var thisClass = this; 1845 maxPromise.then(function () { 1846 var amountErrors = thisClass.findElements('.minimum-amount, .maximum-amount, .recras-product-dependency'); 1847 1848 if (amountErrors.length > 0) { 1849 thisClass.nextSectionActive(null, '.recras-amountsform'); 1850 datePickerEl.setAttribute('disabled', 'disabled'); 1851 return; 1852 } 1853 1854 thisClass.nextSectionActive('.recras-amountsform', '.recras-datetime'); 1855 1856 if (!thisClass.hasAtLeastOneProduct(thisClass.selectedPackage)) { 1857 return; 1858 } 1859 1860 thisClass.loadingIndicatorShow(thisClass.findElement('label[for="recras-onlinebooking-date"]')); 1861 var startDate = new Date(); 1862 var endDate = new Date(); 1863 endDate.setMonth(endDate.getMonth() + 4); 1864 endDate.setDate(0); // Set to 0th day of the month = last day of previous month 1865 1866 if (!thisClass.prefilledDate) { 1867 thisClass.getAvailableDaysInPeriod(thisClass.selectedPackage.id, startDate, endDate); 1868 return; 1869 } 1870 1871 var date = thisClass.prefilledDate; 1872 startDate = new Date(date); 1873 endDate = new Date(date); 1874 endDate.setDate(endDate.getDate() + 1); 1875 thisClass.getAvailableDays(thisClass.selectedPackage.id, startDate, endDate).then(function (availableDays) { 1876 if (availableDays.includes(RecrasDateHelper.datePartOnly(date))) { 1877 thisClass.toggleDateField('hide'); 1878 thisClass.calendarOnDateSelect(date, thisClass.selectedPackage.id); 1879 } else { 1880 thisClass.toggleDateField('show'); 1881 thisClass.getAvailableDaysInPeriod(thisClass.selectedPackage.id, startDate, endDate); 1882 } 1883 }); 1884 }); 1885 } 1886 }, { 1887 key: "getAvailableDaysInPeriod", 1888 value: function getAvailableDaysInPeriod(packageId, startDate, endDate) { 1889 var _this31 = this; 1890 1891 var datePickerEl = this.findElement('.recras-onlinebooking-date'); 1892 this.getAvailableDays(packageId, startDate, endDate).then(function (availableDays) { 1893 _this31.loadingIndicatorHide(); 1894 1895 if (datePickerEl.value && availableDays.indexOf(datePickerEl.value) === -1) { 1896 datePickerEl.value = ''; 1897 1898 _this31.clearTimes(); 1899 } else { 1900 datePickerEl.removeAttribute('disabled'); 1901 } 1902 }); 1903 } 1904 }, { 1905 key: "updateProductPrice", 1906 value: function updateProductPrice(el) { 1907 var priceEl = el.parentNode.querySelector('.recras-price'); 1908 var amount = parseInt(el.value, 10); 1909 1910 if (isNaN(amount)) { 1911 amount = 0; 1912 } 1913 1914 if (amount > 0) { 1915 priceEl.classList.remove('recrasUnitPrice'); 1916 } else { 1917 priceEl.classList.add('recrasUnitPrice'); 1918 } 1919 1920 amount = Math.max(amount, 1); 1921 priceEl.innerHTML = this.formatPrice(amount * el.dataset.price); 1922 } 1923 }, {
1924 key: "validPaymentMethod", 1925 value: function validPaymentMethod(pack, method) { 1926 return this.paymentMethods(pack).indexOf(method) > -1; 1927 } 1928 }]); 1929 1930 return RecrasBooking; 1931}(); 1932 1933var RecrasCalendarHelper = /*#__PURE__*/function () { 1934 function RecrasCalendarHelper() { 1935 _classCallCheck(this, RecrasCalendarHelper); 1936 } 1937 1938 _createClass(RecrasCalendarHelper, null, [{ 1939 key: "defaultOptions", 1940 value: function defaultOptions() { 1941 return { 1942 firstDay: 1, 1943 // Monday 1944 minDate: new Date(), 1945 numberOfMonths: 2, 1946 reposition: false, 1947 position: 'bottom right', 1948 toString: function toString(date) { 1949 return RecrasDateHelper.toString(date); 1950 } 1951 }; 1952 } 1953 }, { 1954 key: "i18n", 1955 value: function i18n(languageHelper) { 1956 return { 1957 previousMonth: languageHelper.translate('DATE_PICKER_PREVIOUS_MONTH'), 1958 nextMonth: languageHelper.translate('DATE_PICKER_NEXT_MONTH'), 1959 months: [languageHelper.translate('DATE_PICKER_MONTH_JANUARY'), languageHelper.translate('DATE_PICKER_MONTH_FEBRUARY'), languageHelper.translate('DATE_PICKER_MONTH_MARCH'), languageHelper.translate('DATE_PICKER_MONTH_APRIL'), languageHelper.translate('DATE_PICKER_MONTH_MAY'), languageHelper.translate('DATE_PICKER_MONTH_JUNE'), languageHelper.translate('DATE_PICKER_MONTH_JULY'), languageHelper.translate('DATE_PICKER_MONTH_AUGUST'), languageHelper.translate('DATE_PICKER_MONTH_SEPTEMBER'), languageHelper.translate('DATE_PICKER_MONTH_OCTOBER'), languageHelper.translate('DATE_PICKER_MONTH_NOVEMBER'), languageHelper.translate('DATE_PICKER_MONTH_DECEMBER')], 1960 weekdays: [languageHelper.translate('DATE_PICKER_DAY_SUNDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_MONDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_TUESDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_WEDNESDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_THURSDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_FRIDAY_LONG'), languageHelper.translate('DATE_PICKER_DAY_SATURDAY_LONG')], 1961 weekdaysShort: [languageHelper.translate('DATE_PICKER_DAY_SUNDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_MONDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_TUESDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_WEDNESDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_THURSDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_FRIDAY_SHORT'), languageHelper.translate('DATE_PICKER_DAY_SATURDAY_SHORT')] 1962 }; 1963 } 1964 }, { 1965 key: "loadScript", 1966 value: function loadScript() { 1967 return new Promise(function (resolve, reject) { 1968 var scriptID = 'recrasPikaday'; // Only load script once 1969 1970 if (document.getElementById(scriptID)) { 1971 resolve(true); 1972 } 1973 1974 var script = document.createElement('script'); 1975 script.id = scriptID; 1976 script.src = 'https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.8.2/pikaday.min.js'; 1977 script.addEventListener('load', function () { 1978 return resolve(script); 1979 }, false); 1980 script.addEventListener('error', function () { 1981 return reject(script); 1982 }, false); 1983 document.head.appendChild(script); 1984 }); 1985 } 1986 }]); 1987 1988 return RecrasCalendarHelper; 1989}(); 1990 1991var RecrasContactForm = /*#__PURE__*/function () { 1992 function RecrasContactForm() { 1993 var _this32 = this; 1994 1995 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1996 1997 _classCallCheck(this, RecrasContactForm); 1998 1999 this.languageHelper = new RecrasLanguageHelper(); 2000 2001 if (!(options instanceof RecrasOptions)) { 2002 throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); 2003 } 2004 2005 this.options = options; 2006 2007 if (!this.options.getFormId()) { 2008 throw new Error(this.languageHelper.translate('ERR_NO_FORM')); 2009 } 2010 2011 this.checkboxEventListeners = []; 2012 this.eventHelper = new RecrasEventHelper(); 2013 this.eventHelper.setEvents(this.options.getAnalyticsEvents()); 2014 this.element = this.options.getElement(); 2015 this.element.classList.add('recras-contactform-wrapper'); 2016 this.languageHelper.setOptions(options); 2017 2018 if (RecrasLanguageHelper.isValid(this.options.getLocale())) { 2019 this.languageHelper.setLocale(this.options.getLocale()); 2020 } 2021 2022 this.fetchJson = function (url) { 2023 return RecrasHttpHelper.fetchJson(url, _this32.error.bind(_this32)); 2024 }; 2025 2026 this.postJson = function (url, data) { 2027 return RecrasHttpHelper.postJson(_this32.options.getApiBase() + url, data, _this32.error.bind(_this32)); 2028 }; 2029 2030 RecrasCSSHelper.loadCSS('global'); 2031 this.GENDERS = { 2032 onbekend: 'GENDER_UNKNOWN', 2033 man: 'GENDER_MALE', 2034 vrouw: 'GENDER_FEMALE' 2035 }; // https://html.spec.whatwg.org/multipage/form-control-infrastru
2035cture.html#inappropriate-for-the-control 2036 2037 this.AUTOCOMPLETE_OPTIONS = { 2038 'contact.naam': 'organization', 2039 'contact.website': 'url', 2040 'contactpersoon.achternaam': 'family-name', 2041 'contactpersoon.adres': 'address-line1', 2042 'contactpersoon.plaats': 'address-level2', 2043 'contactpersoon.postcode': 'postal-code', 2044 'contactpersoon.voornaam': 'given-name' 2045 }; 2046 } 2047 2048 _createClass(RecrasContactForm, [{ 2049 key: "checkRequiredCheckboxes", 2050 value: function checkRequiredCheckboxes() { 2051 var _this33 = this; 2052 2053 this.removeWarnings(); 2054 var isOkay = true; 2055 2056 _toConsumableArray(this.findElements('.checkboxGroupRequired')).forEach(function (group) { 2057 var checked = group.querySelectorAll('input:checked'); 2058 2059 if (checked.length === 0) { 2060 group.parentNode.querySelector('label').insertAdjacentHTML('beforeend', "<div class=\"recrasError\">".concat(_this33.languageHelper.translate('CONTACT_FORM_CHECKBOX_REQUIRED'), "</div>")); 2061 isOkay = false; 2062 } 2063 }); 2064 2065 return isOkay; 2066 } 2067 }, { 2068 key: "appendHtml", 2069 value: function appendHtml(msg) { 2070 this.element.insertAdjacentHTML('beforeend', msg); 2071 } 2072 }, { 2073 key: "error", 2074 value: function error(msg) { 2075 this.removeErrors('.recras-contactform'); 2076 this.showInlineError(this.findElement('.submitForm'), msg); 2077 } 2078 }, { 2079 key: "findElement", 2080 value: function findElement(querystring) { 2081 return this.element.querySelector(querystring); 2082 } 2083 }, { 2084 key: "findElements", 2085 value: function findElements(querystring) { 2086 return this.element.querySelectorAll(querystring); 2087 } 2088 }, { 2089 key: "isStandalone", 2090 value: function isStandalone(options) { 2091 return !!options.standalone; 2092 } 2093 }, { 2094 key: "generateForm", 2095 value: function generateForm() { 2096 var _this34 = this; 2097 2098 var extraOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2099 var waitFor = []; 2100 2101 if (this.hasCountryField()) { 2102 waitFor.push(this.getCountryList()); 2103 } 2104 2105 if (this.hasBookingDateField() || this.hasRelationDateField()) { 2106 waitFor.push(RecrasCalendarHelper.loadScript()); 2107 RecrasCSSHelper.loadCSS('pikaday'); 2108 } 2109 2110 return Promise.all(waitFor).then(function () { 2111 var standalone = _this34.isStandalone(extraOptions); 2112 2113 var validateText = standalone ? 'novalidate' : ''; 2114 var html = "<form class=\"recras-contactform\" ".concat(validateText, ">"); 2115 2116 if (extraOptions.voucherQuantitySelector) { 2117 html += _this34.quantitySelector(extraOptions.quantityTerm); 2118 } 2119 2120 _this34.contactFormFields.forEach(function (field, idx) { 2121 html += '<div>' + _this34.showField(field, idx) + '</div>'; 2122 }); 2123 2124 if (standalone) { 2125 html += _this34.submitButtonHtml(); 2126 } 2127 2128 html += '</form>'; 2129 return html; 2130 }); 2131 } 2132 }, { 2133 key: "generateJson", 2134 value: function generateJson() { 2135 var formEl = this.options.getElement().querySelector('.recras-contactform'); 2136 var elements = formEl.querySelectorAll('[id^="contactformulier-"], input[type="radio"]:checked'); 2137 var contactForm = {}; 2138 2139 _toConsumableArray(elements).forEach(function (field) { 2140 contactForm[field.dataset.identifier] = field.value; 2141 }); 2142 2143 _toConsumableArray(formEl.querySelectorAll('input[type="checkbox"]:checked')).forEach(function (field) { 2144 if (contactForm[field.dataset.identifier] === undefined) { 2145 contactForm[field.dataset.identifier] = []; 2146 } 2147 2148 contactForm[field.dataset.identifier].push(field.value); 2149 }); 2150 2151 if (contactForm['boeking.datum']) { 2152 contactForm['boeking.datum'] = RecrasDateHelper.formatStringForAPI(contactForm['boeking.datum']); 2153 } 2154 2155 return contactForm; 2156 } 2157 }, {
2158 key: "getContactFormFields", 2159 value: function getContactFormFields() { 2160 var _this35 = this; 2161 2162 return this.fetchJson(this.options.getApiBase() + 'contactformulieren/' + this.options.getFormId() + '?embed=Velden').then(function (form) { 2163 _this35.contactFormFields = form.Velden; 2164 _this35.packages = _this35.sortPackages(form.Arrangementen); 2165 return _this35.contactFormFields; 2166 }); 2167 } 2168 }, { 2169 key: "getCountryList", 2170 value: function getCountryList() { 2171 var _this36 = this; 2172 2173 return this.fetchJson('https://cdn.rawgit.com/umpirsky/country-list/ddabf3a8/data/' + this.languageHelper.locale + '/country.json').then(function (json) { 2174 _this36.countries = json; 2175 return _this36.countries; 2176 }); 2177 } 2178 }, { 2179 key: "sortPackages", 2180 value: function sortPackages(packs) { 2181 return packs.sort(function (a, b) { 2182 // Prioritise package name 2183 if (a.arrangement < b.arrangement) { 2184 return -1; 2185 } 2186 2187 if (a.arrangement > b.arrangement) { 2188 return 1; 2189 } // Sort by ID in the off chance that two packages are named the same 2190 2191 2192 if (a.id < b.id) { 2193 return -1; 2194 } 2195 2196 if (a.id > b.id) { 2197 return 1; 2198 } // This cannot happen 2199 2200 2201 return 0; 2202 }); 2203 } 2204 }, { 2205 key: "getInvalidFields", 2206 value: function getInvalidFields() { 2207 var invalid = []; 2208 var required = this.getEmptyRequiredFields(); 2209 var els = this.findElements('.recras-contactform :invalid'); 2210 2211 for (var _i14 = 0; _i14 < els.length; _i14++) { 2212 var el = els[_i14]; 2213 2214 if (!required.includes(el)) { 2215 invalid.push(el); 2216 } 2217 } 2218 2219 return invalid; 2220 } 2221 }, { 2222 key: "getEmptyRequiredFields", 2223 value: function getEmptyRequiredFields() { 2224 var isEmpty = []; 2225 var els = this.findElements('.recras-contactform :required'); 2226 2227 for (var _i16 = 0; _i16 < els.length; _i16++) { 2228 var el = els[_i16]; 2229 2230 if (el.value === undefined || el.value === '') { 2231 isEmpty.push(el); 2232 } 2233 } 2234 2235 return isEmpty; 2236 } 2237 }, { 2238 key: "getRelationExtraDateFields", 2239 value: function getRelationExtraDateFields() { 2240 return this.contactFormFields.filter(function (field) { 2241 return field.soort_invoer === 'contact.extra' && field.input_type === 'date'; 2242 }); 2243 } 2244 }, { 2245 key: "hasFieldOfType", 2246 value: function hasFieldOfType(identifier) { 2247 return this.contactFormFields.filter(function (field) { 2248 return field.field_identifier === identifier; 2249 }).length > 0; 2250 } 2251 }, { 2252 key: "hasBookingDateField", 2253 value: function hasBookingDateField() { 2254 return this.hasFieldOfType('boeking.datum'); 2255 } 2256 }, { 2257 key: "hasCountryField", 2258 value: function hasCountryField() { 2259 return this.hasFieldOfType('contact.landcode'); 2260 } 2261 }, { 2262 key: "hasPackageField", 2263 value: function hasPackageField() { 2264 return this.hasFieldOfType('boeking.arrangement'); 2265 } 2266 }, { 2267 key: "hasRelationDateField", 2268 value: function hasRelationDateField() { 2269 return this.getRelationExtraDateFields().length > 0; 2270 } 2271 }, { 2272 key: "isEmpty", 2273 value: function isEmpty() { 2274 var els = this.findElements('.recras-contactform input, .recras-contactform select, .recras-contactform textarea'); 2275 2276 var formValues = _toConsumableArray(els).map(function (el) { 2277 return el.value; 2278 }); 2279 2280 return !formValues.some(function (v) { 2281 return v !== ''; 2282 }); 2283 } 2284 }, {
2285 key: "isValid", 2286 value: function isValid() { 2287 return this.findElement('.recras-contactform').checkValidity(); 2288 } 2289 }, { 2290 key: "loadingIndicatorHide", 2291 value: function loadingIndicatorHide() { 2292 _toConsumableArray(document.querySelectorAll('.recrasLoadingIndicator')).forEach(function (el) { 2293 el.parentNode.removeChild(el); 2294 }); 2295 } 2296 }, { 2297 key: "loadingIndicatorShow", 2298 value: function loadingIndicatorShow(afterEl) { 2299 if (!afterEl) { 2300 return; 2301 } 2302 2303 afterEl.insertAdjacentHTML('beforeend', "<span class=\"recrasLoadingIndicator\">".concat(this.languageHelper.translate('LOADING'), "</span>")); 2304 } 2305 }, { 2306 key: "quantitySelector", 2307 value: function quantitySelector(quantityTerm) { 2308 if (!quantityTerm) { 2309 quantityTerm = this.languageHelper.translate('VOUCHER_QUANTITY'); 2310 } 2311 2312 return "<div>\n <label for=\"number-of-vouchers\">".concat(quantityTerm, "</label>\n <input type=\"number\" id=\"number-of-vouchers\" class=\"number-of-vouchers\" min=\"1\" max=\"100\" value=\"1\" required>\n </div>"); 2313 } 2314 }, { 2315 key: "removeErrors", 2316 value: function removeErrors() { 2317 var parentQuery = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 2318 2319 _toConsumableArray(this.findElements(parentQuery + ' .booking-error')).forEach(function (el) { 2320 el.parentNode.removeChild(el); 2321 }); 2322 } 2323 }, { 2324 key: "removeWarnings", 2325 value: function removeWarnings() { 2326 _toConsumableArray(this.findElements('.recrasError')).forEach(function (el) { 2327 el.parentNode.removeChild(el); 2328 }); 2329 2330 _toConsumableArray(this.findElements('.recras-success')).forEach(function (el) { 2331 el.parentNode.removeChild(el); 2332 }); 2333 } 2334 }, { 2335 key: "hasEmptyRequiredFields", 2336 value: function hasEmptyRequiredFields() { 2337 return this.getEmptyRequiredFields().length > 0; 2338 } 2339 }, { 2340 key: "showField", 2341 value: function showField(field, idx) { 2342 var _this37 = this; 2343 2344 if (field.soort_invoer === 'header') { 2345 return "<h3>".concat(field.naam, "</h3>"); 2346 } 2347 2348 var today = RecrasDateHelper.toString(new Date()); 2349 var timePattern = '(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9])'; 2350 var label = this.showLabel(field, idx); 2351 var attrRequired = field.verplicht ? 'required' : ''; 2352 var classes; 2353 var html; 2354 var placeholder; 2355 var fixedAttributes = "id=\"contactformulier-".concat(idx, "\" name=\"contactformulier").concat(idx, "\" ").concat(attrRequired, " data-identifier=\"").concat(field.field_identifier, "\""); 2356 2357 switch (field.soort_invoer) { 2358 case 'contactpersoon.geslacht': 2359 html = "<select ".concat(fixedAttributes, " autocomplete=\"sex\">"); 2360 Object.keys(this.GENDERS).forEach(function (key) { 2361 html += "<option value=\"".concat(key, "\">").concat(_this37.languageHelper.translate(_this37.GENDERS[key])); 2362 }); 2363 html += '</select>'; 2364 return label + html; 2365 2366 case 'keuze': 2367 classes = ['checkboxGroup']; 2368 2369 if (field.verplicht) { 2370 classes.push('checkboxGroupRequired'); 2371 } 2372 2373 html = "<div class=\"".concat(classes.join(' '), "\">"); 2374 field.mogelijke_keuzes.forEach(function (choice) { 2375 html += "<label><input type=\"checkbox\" name=\"contactformulier".concat(idx, "\" value=\"").concat(choice, "\" data-identifier=\"").concat(field.field_identifier, "\">").concat(choice, "</label>"); 2376 }); 2377 html += '</div>'; 2378 return label + html; 2379 2380 case 'keuze_enkel': 2381 case 'contact.soort_klant': 2382 html = "<div class=\"radioGroup\">";
2383 field.mogelijke_keuzes.forEach(function (choice) { 2384 html += "<label><input type=\"radio\" name=\"contactformulier".concat(idx, "\" value=\"").concat(choice, "\" ").concat(attrRequired, " data-identifier=\"").concat(field.field_identifier, "\">").concat(choice, "</label>"); 2385 }); 2386 html += "</div>"; 2387 return label + html; 2388 2389 case 'veel_tekst': 2390 return label + "<textarea ".concat(fixedAttributes, "></textarea>"); 2391 2392 case 'contactpersoon.telefoon1': 2393 case 'contactpersoon.telefoon2': 2394 return label + "<input type=\"tel\" ".concat(fixedAttributes, " autocomplete=\"tel\">"); 2395 2396 case 'contactpersoon.email1': 2397 case 'contactpersoon.email2': 2398 return label + "<input type=\"email\" ".concat(fixedAttributes, " autocomplete=\"email\">"); 2399 2400 case 'contactpersoon.nieuwsbrieven': 2401 classes = ['checkboxGroup']; 2402 2403 if (field.verplicht) { 2404 classes.push('checkboxGroupRequired'); 2405 } 2406 2407 html = "<div class=\"".concat(classes.join(' '), "\">"); 2408 Object.keys(field.newsletter_options).forEach(function (key) { 2409 html += "<label><input type=\"checkbox\" name=\"contactformulier".concat(idx, "\" value=\"").concat(key, "\" data-identifier=\"").concat(field.field_identifier, "\">").concat(field.newsletter_options[key], "</label>"); 2410 }); 2411 html += '</div>'; 2412 return label + html; 2413 2414 case 'contact.landcode': 2415 html = "<select ".concat(fixedAttributes, " autocomplete=\"country\">"); 2416 Object.keys(this.countries).forEach(function (code) { 2417 var selectedText = code.toUpperCase() === _this37.options.getDefaultCountry() ? 'selected' : ''; 2418 html += "<option value=\"".concat(code, "\" ").concat(selectedText, ">").concat(_this37.countries[code]); 2419 }); 2420 html += '</select>'; 2421 return label + html; 2422 2423 case 'boeking.datum': 2424 placeholder = this.languageHelper.translate('DATE_FORMAT'); 2425 return label + "<input type=\"text\" ".concat(fixedAttributes, " min=\"").concat(today, "\" placeholder=\"").concat(placeholder, "\" autocomplete=\"off\">"); 2426 2427 case 'boeking.groepsgrootte': 2428 return label + "<input type=\"number\" ".concat(fixedAttributes, " min=\"1\">"); 2429 2430 case 'boeking.starttijd': 2431 placeholder = this.languageHelper.translate('TIME_FORMAT'); 2432 return label + "<input type=\"time\" ".concat(fixedAttributes, " placeholder=\"").concat(placeholder, "\" pattern=\"").concat(timePattern, "\">"); 2433 2434 case 'boeking.arrangement': 2435 var preFilledPackage = this.options.getPackageId(); 2436 2437 if (field.verplicht && this.packages.length === 1) { 2438 var pack = this.packages[0]; 2439 html = "<select ".concat(fixedAttributes, ">\n <option value=\"").concat(pack.id, "\" selected>").concat(pack.arrangement, "\n </select>"); 2440 return label + html; 2441 } 2442 2443 html = "<select ".concat(fixedAttributes, ">"); 2444 html += "<option value=\"\">"; 2445 this.packages.forEach(function (pack) { 2446 var selText = preFilledPackage && preFilledPackage === pack.id ? 'selected' : ''; 2447 html += "<option value=\"".concat(pack.id, "\" ").concat(selText, ">").concat(pack.arrangement); 2448 }); 2449 html += '</select>'; 2450 return label + html; 2451 2452 case 'contact.extra': 2453 switch (field.input_type) { 2454 case 'number': 2455 return label + "<input type=\"number\" ".concat(fixedAttributes, " autocomplete=\"off\">"); 2456 2457 case 'date': 2458 case 'text': 2459 return label + "<input type=\"text\" ".concat(fixedAttributes, " maxlength=\"200\">"); 2460 2461 case 'multiplechoice': 2462 classes = ['checkboxGroup']; 2463 2464 if (field.verplicht) { 2465 classes.push('checkboxGroupRequired'); 2466 } 2467 2468 html = "<div class=\"".concat(classes.join(' '), "\">");
2469 field.mogelijke_keuzes.forEach(function (choice) { 2470 html += "<label><input type=\"checkbox\" name=\"contactformulier".concat(idx, "\" value=\"").concat(choice, "\" data-identifier=\"").concat(field.field_identifier, "\">").concat(choice, "</label>"); 2471 }); 2472 html += '</div>'; 2473 return label + html; 2474 2475 case 'singlechoice': 2476 html = "<div class=\"radioGroup\">"; 2477 field.mogelijke_keuzes.forEach(function (choice) { 2478 html += "<label><input type=\"radio\" name=\"contactformulier".concat(idx, "\" value=\"").concat(choice, "\" ").concat(attrRequired, " data-identifier=\"").concat(field.field_identifier, "\">").concat(choice, "</label>"); 2479 }); 2480 html += "</div>"; 2481 return label + html; 2482 2483 default: 2484 console.debug('Unknown type', field.input_type, field); 2485 return label + "<input type=\"text\" ".concat(fixedAttributes, ">"); 2486 } 2487 2488 case 'contact.website': //TODO: type=url ? 2489 2490 default: 2491 var autocomplete = this.AUTOCOMPLETE_OPTIONS[field.soort_invoer] ? this.AUTOCOMPLETE_OPTIONS[field.soort_invoer] : ''; 2492 return label + "<input type=\"text\" ".concat(fixedAttributes, " autocomplete=\"").concat(autocomplete, "\">"); 2493 } 2494 } 2495 }, { 2496 key: "showForm", 2497 value: function showForm() { 2498 var _this38 = this; 2499 2500 this.loadingIndicatorShow(this.element); 2501 return this.getContactFormFields().then(function () { 2502 return _this38.generateForm({ 2503 standalone: true 2504 }); 2505 }).then(function (html) { 2506 _this38.appendHtml(html); 2507 2508 _toConsumableArray(_this38.findElements('.checkboxGroupRequired')).forEach(function (group) { 2509 _toConsumableArray(group.querySelectorAll('input')).forEach(function (el) { 2510 el.addEventListener('change', _this38.checkRequiredCheckboxes.bind(_this38)); 2511 }); 2512 }); 2513 2514 _this38.findElement('.recras-contactform').addEventListener('submit', _this38.submitForm.bind(_this38)); 2515 2516 if (_this38.hasBookingDateField()) { 2517 var pikadayOptions = _extends(RecrasCalendarHelper.defaultOptions(), { 2518 field: _this38.findElement('[data-identifier="boeking.datum"]'), 2519 i18n: RecrasCalendarHelper.i18n(_this38.languageHelper), 2520 numberOfMonths: 1, 2521 parse: RecrasDateHelper.parseMDY 2522 }); 2523 2524 new Pikaday(pikadayOptions); 2525 } 2526 2527 if (_this38.hasRelationDateField()) { 2528 var fields = _this38.getRelationExtraDateFields(); 2529 2530 var thisYear = new Date().getFullYear(); 2531 2532 var _pikadayOptions = _extends(RecrasCalendarHelper.defaultOptions(), { 2533 i18n: RecrasCalendarHelper.i18n(_this38.languageHelper), 2534 numberOfMonths: 1, 2535 yearRange: [thisYear - 90, thisYear + 10] 2536 }); 2537 2538 delete _pikadayOptions.minDate; 2539 2540 for (var _i18 = 0; _i18 < fields.length; _i18++) { 2541 var field = fields[_i18]; 2542 _pikadayOptions.field = _this38.findElement("[data-identifier=\"".concat(field.field_identifier, "\"]")); 2543 new Pikaday(_pikadayOptions); 2544 } 2545 } 2546 2547 _this38.loadingIndicatorHide(); 2548 }); 2549 } 2550 }, { 2551 key: "showInlineError", 2552 value: function showInlineError(element, errorMsg) { 2553 element.parentNode.insertAdjacentHTML('afterend', "<div class=\"booking-error\">".concat(errorMsg, "</div>")); 2554 } 2555 }, {
2556 key: "showErrors", 2557 value: function showErrors() { 2558 var errors = []; 2559 2560 for (var _i20 = 0, _this$getEmptyRequire2 = this.getEmptyRequiredFields(); _i20 < _this$getEmptyRequire2.length; _i20++) { 2561 var el = _this$getEmptyRequire2[_i20]; 2562 var labelEl = el.parentNode.querySelector('label'); 2563 var requiredText = this.languageHelper.translate('CONTACT_FORM_FIELD_REQUIRED', { 2564 FIELD_NAME: labelEl.innerText 2565 }); 2566 errors.push(requiredText); 2567 } 2568 2569 for (var _i22 = 0, _this$getInvalidField2 = this.getInvalidFields(); _i22 < _this$getInvalidField2.length; _i22++) { 2570 var _el = _this$getInvalidField2[_i22]; 2571 2572 var parentEl = _el.closest('div'); 2573 2574 if (parentEl.classList.contains('radioGroup')) { 2575 parentEl = parentEl.parentNode.closest('div'); 2576 } 2577 2578 var _labelEl = parentEl.querySelector('label'); 2579 2580 console.log(_labelEl, parentEl.querySelectorAll('label')); 2581 var invalidText = this.languageHelper.translate('CONTACT_FORM_FIELD_INVALID', { 2582 FIELD_NAME: _labelEl.innerText 2583 }); 2584 errors.push(invalidText); 2585 } 2586 2587 errors = _toConsumableArray(new Set(errors)); // Only unique text 2588 2589 this.findElement('button[type="submit"]').insertAdjacentHTML('afterend', "<div class=\"booking-error\"><ul><li>".concat(errors.join('<li>'), "</ul></div>")); 2590 } 2591 }, { 2592 key: "showLabel", 2593 value: function showLabel(field, idx) { 2594 var labelText = field.naam; 2595 2596 if (field.verplicht) { 2597 labelText += "<span class=\"recras-contactform-required\" title=\"".concat(this.languageHelper.translate('ATTR_REQUIRED'), "\"></span>"); 2598 } 2599 2600 return "<label for=\"contactformulier-".concat(idx, "\">").concat(labelText, "</label>"); 2601 } 2602 }, { 2603 key: "submitButtonHtml", 2604 value: function submitButtonHtml() { 2605 return "<button type=\"submit\" class=\"submitForm\">".concat(this.languageHelper.translate('BUTTON_SUBMIT_CONTACT_FORM'), "</button>"); 2606 } 2607 }, { 2608 key: "submitForm", 2609 value: function submitForm(e) { 2610 var _this39 = this; 2611 2612 e.preventDefault(); 2613 var submitButton = this.findElement('.submitForm'); 2614 this.removeErrors('.recras-contactform'); 2615 2616 if (this.isEmpty()) { 2617 submitButton.parentNode.insertAdjacentHTML('beforeend', "<div class=\"booking-error\">".concat(this.languageHelper.translate('ERR_CONTACT_FORM_EMPTY'), "</div>")); 2618 return false; 2619 } else if (this.hasEmptyRequiredFields() || !this.isValid()) { 2620 this.showErrors(); 2621 return false; 2622 } 2623 2624 if (!this.checkRequiredCheckboxes()) { 2625 return false; 2626 } 2627 2628 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_CONTACT_FORM, RecrasEventHelper.EVENT_CONTACT_FORM_SUBMIT, null, this.options.getFormId()); 2629 this.loadingIndicatorHide(); 2630 this.loadingIndicatorShow(submitButton); 2631 submitButton.setAttribute('disabled', 'disabled'); 2632 this.postJson('contactformulieren/' + this.options.getFormId() + '/opslaan', this.generateJson()).then(function (json) { 2633 if (json.success) { 2634 if (_this39.options.getRedirectUrl()) { 2635 window.top.location.href = _this39.options.getRedirectUrl(); 2636 } else { 2637 _this39.element.scrollIntoView({ 2638 behavior: 'smooth' 2639 }); 2640 2641 _this39.element.insertAdjacentHTML('afterbegin', "<p class=\"recras-success\">".concat(_this39.languageHelper.translate('CONTACT_FORM_SUBMIT_SUCCESS'), "</p>")); 2642 2643 submitButton.parentNode.reset(); 2644 } 2645 } else { 2646 _this39.error(_this39.languageHelper.translate('CONTACT_FORM_SUBMIT_FAILED')); 2647 } 2648 2649 submitButton.removeAttribute('disabled'); 2650 2651 _this39.loadingIndicatorHide(); 2652 }); 2653 return false;
2654 } 2655 }]); 2656 2657 return RecrasContactForm; 2658}(); 2659 2660var RecrasCSSHelper = /*#__PURE__*/function () { 2661 function RecrasCSSHelper() { 2662 _classCallCheck(this, RecrasCSSHelper); 2663 } 2664 2665 _createClass(RecrasCSSHelper, null, [{ 2666 key: "cssBooking", 2667 value: function cssBooking() { 2668 return "\n.recras-onlinebooking {\n max-width: 800px;\n}\n.recras-onlinebooking > form + form, .recras-finalise {\n border-top: 2px solid #dedede; /* Any love for Kirby out there? */\n}\n.recras-amountsform > div {\n display: grid;\n grid-template-columns: 1fr 5em 7em;\n}\n.recras-amountsform input {\n width: auto; /* Firefox fix */\n}\n.recras-input-invalid {\n border: 1px solid hsl(0, 50%, 50%);\n}\n.booking-error, .minimum-amount {\n color: hsl(0, 50%, 50%);\n}\n.recras-success {\n color: hsl(120, 40%, 40%);\n}\n.minimum-amount {\n padding-left: 0.5em;\n}\n.recras-datetime {\n display: grid;\n grid-template-columns: 30% 70%;\n}\n.recras-datetime > * {\n margin: 0.25em 0;\n}\n.recras-datetime label {\n display: block;\n}\n.recras-datetime input, .recras-datetime select {\n max-width: 12em;\n}\n.time-preview {\n padding-right: 0.5em;\n}\n.recrasUnitPrice {\n opacity: 0.5;\n}\n.recras-onlinebooking .recrasHidden {\n display: none;\n}\n"; 2669 } 2670 }, { 2671 key: "cssGlobal", 2672 value: function cssGlobal() { 2673 return "\n.latestError, .recrasError {\n color: hsl(0, 50%, 50%);\n}\n.recras-onlinebooking > *:not(.latestError):not(.recrasLoadingIndicator) {\n padding: 1em 0;\n}\n.recras-datetime, .recras-discounts > div, .recras-contactform > div {\n display: grid;\n grid-template-columns: 1fr 12em;\n}\n.recras-contactform > div {\n padding-bottom: 0.25em;\n padding-top: 0.25em;\n}\n.recras-contactform label {\n display: block;\n}\n.recras-amountsform .recras-full-width {\n display: block;\n}\n\n.recrasLoadingIndicator {\n animation: recrasSpinner 1.1s infinite linear;\n border: 0.2em solid rgba(0, 0, 0, 0.2);\n border-left-color: rgba(0, 0, 0, 0.5);\n border-radius: 50%;\n display: inline-block;\n height: 2em;\n overflow: hidden;\n text-indent: -100vw;\n width: 2em;\n}\n@keyframes recrasSpinner {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\nbutton .recrasLoadingIndicator, label .recrasLoadingIndicator {\n height: 1em;\n vertical-align: middle;\n width: 1em;\n}\nbutton .recrasLoadingIndicator {\n margin-left: 0.5em;\n}\n.bookPackage, .submitForm, .buyTemplate {\n font: inherit;\n font-weight: bold;\n padding: 0.5em 2em;\n}\n@media (max-width: 520px) {\n .pika-single {\n max-width: 256px; /* Single month is 240px + 2x8px margin */\n }\n}\n"; 2674 } 2675 }, { 2676 key: "insertIntoHead", 2677 value: function insertIntoHead(el) { 2678 document.head.insertAdjacentElement('afterbegin', el); 2679 } 2680 }, { 2681 key: "loadInlineCss", 2682 value: function loadInlineCss(cssName, inlineCss) { 2683 var styleEl = document.createElement('style'); 2684 styleEl.id = 'recras-css-' + cssName; 2685 styleEl.innerHTML = inlineCss; 2686 RecrasCSSHelper.insertIntoHead(styleEl); 2687 } 2688 }, { 2689 key: "loadExternalCss", 2690 value: function loadExternalCss(cssName, url) { 2691 var linkEl = document.createElement('link'); 2692 linkEl.id = 'recras-css-' + cssName; 2693 linkEl.setAttribute('rel', 'stylesheet'); 2694 linkEl.setAttribute('type', 'text/css'); 2695 linkEl.setAttribute('href', url); 2696 RecrasCSSHelper.insertIntoHead(linkEl); 2697 } 2698 }, { 2699 key: "loadCSS", 2700 value: function loadCSS(cssName) { 2701 var inlineCss; 2702 var url; 2703 2704 switch (cssName) { 2705 case 'booking': 2706 inlineCss = this.cssBooking(); 2707 break; 2708 2709 case 'global': 2710 inlineCss = this.cssGlobal(); 2711 break; 2712 2713 case 'pikaday': 2714 url = 'https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.8.2/css/pikaday.min.css'; 2715 break; 2716 2717 default: 2718 console.warn('Unknown CSS'); 2719 break; 2720 } 2721 2722 if (document.getElementById('recras-css-' + cssName)) { 2723 return; 2724 } 2725 2726 if (inlineCss) { 2727 RecrasCSSHelper.loadInlineCss(cssName, inlineCss); 2728 } 2729 2730 if (url) { 2731 RecrasCSSHelper.loadExternalCss(cssName, url); 2732 } 2733 } 2734 }]); 2735 2736 return RecrasCSSHelper; 2737}(); 2738 2739var RecrasDateHelper = /*#__PURE__*/function () { 2740 function RecrasDateHelper() { 2741 _classCallCheck(this, RecrasDateHelper); 2742 } 2743 2744 _createClass(RecrasDateHelper, null, [{ 2745 key: "clone", 2746 value: function clone(date) { 2747 return new Date(date.getTime()); 2748 } 2749 }, {
2750 key: "datePartOnly", 2751 value: function datePartOnly(date) { 2752 var x = new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000); // Fix off-by-1 errors 2753 2754 return x.toISOString().substr(0, 10); // Format as 2018-03-13 2755 } 2756 }, { 2757 key: "formatStringForAPI", 2758 value: function formatStringForAPI(date) { 2759 // Handle DD-MM-YYYY pattern in code 2760 var datePatternDMY = '(0[1-9]|1[0-9]|2[0-9]|3[01])-(0[1-9]|1[012])-([0-9]{4})'; 2761 var dmyMatches = date.match(datePatternDMY); 2762 2763 if (dmyMatches) { 2764 return dmyMatches[3] + '-' + dmyMatches[2] + '-' + dmyMatches[1]; 2765 } // Let API handle the rest. That way, the user will get an error if the input is invalid 2766 2767 2768 return date; 2769 } 2770 }, { 2771 key: "parseMDY", 2772 value: function parseMDY(dateStr) { 2773 var parts = dateStr.split('-'); 2774 var day = parseInt(parts[0], 10); 2775 var month = parseInt(parts[1], 10) - 1; 2776 var year = parseInt(parts[2], 10); 2777 return new Date(year, month, day); 2778 } 2779 }, { 2780 key: "setTimeForDate", 2781 value: function setTimeForDate(date, timeStr) { 2782 date.setHours(timeStr.substr(0, 2), timeStr.substr(3, 2)); 2783 return date; 2784 } 2785 }, { 2786 key: "timePartOnly", 2787 value: function timePartOnly(date) { 2788 return date.toTimeString().substr(0, 5); // Format at 09:00 2789 } 2790 }, { 2791 key: "toString", 2792 value: function toString(date) { 2793 var x = new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000); // Fix off-by-1 errors 2794 2795 x = x.toISOString(); 2796 return x.substr(8, 2) + '-' + x.substr(5, 2) + '-' + x.substr(0, 4); 2797 } 2798 }]); 2799 2800 return RecrasDateHelper; 2801}(); 2802 2803var RecrasEventHelper = /*#__PURE__*/function () { 2804 function RecrasEventHelper() { 2805 _classCallCheck(this, RecrasEventHelper); 2806 2807 this.analyticsEnabled = false; 2808 this.eventsEnabled = RecrasEventHelper.allEvents(); 2809 } 2810 2811 _createClass(RecrasEventHelper, [{ 2812 key: "eventEnabled", 2813 value: function eventEnabled(name) { 2814 return this.eventsEnabled.includes(name); 2815 } 2816 }, { 2817 key: "ga4EventMap", 2818 value: function ga4EventMap(action) { 2819 var _map; 2820 2821 var map = (_map = {}, _defineProperty(_map, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, 'select_content'), _defineProperty(_map, RecrasEventHelper.EVENT_BOOKING_REDIRECT_PAYMENT, 'begin_checkout'), _defineProperty(_map, RecrasEventHelper.EVENT_VOUCHER_TEMPLATE_CHANGED, 'select_content'), _defineProperty(_map, RecrasEventHelper.EVENT_VOUCHER_REDIRECT_PAYMENT, 'begin_checkout'), _map); 2822 2823 if (map[action] === undefined) { 2824 return false; 2825 } 2826 2827 return map[action]; 2828 } 2829 }, { 2830 key: "sendAnalyticsEvent", 2831 value: function sendAnalyticsEvent(cat, action) { 2832 var label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 2833 var value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined; 2834 var ga4Value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined; 2835 2836 if (typeof window.gtag !== 'function') { 2837 return; 2838 } 2839 2840 if (this.ga4EventMap(action) && ga4Value) { 2841 // v4 2842 window.gtag('event', this.ga4EventMap(action), ga4Value); 2843 return; 2844 } // Global Site Tag (v3) 2845 2846 2847 var eventData = { 2848 event_category: RecrasEventHelper.PREFIX_GLOBAL + ':' + cat 2849 }; 2850 2851 if (label) { 2852 eventData.event_label = label; 2853 } 2854 2855 if (value) { 2856 eventData.value = value; 2857 } 2858 2859 window.gtag('event', action, eventData); 2860 } 2861 }, { 2862 key: "sendEvent", 2863 value: function sendEvent(cat, action) { 2864 var label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; 2865 var value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined; 2866 var ga4Value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined; 2867 2868 if (this.analyticsEnabled && this.eventEnabled(action)) { 2869 this.sendAnalyticsEvent(cat, action, label, value, ga4Value); 2870 } 2871 2872 var event = new Event(RecrasEventHelper.PREFIX_GLOBAL + ':' + cat + ':' + action); 2873 return document.dispatchEvent(event); 2874 } 2875 }, {
2876 key: "setAnalytics", 2877 value: function setAnalytics(bool) { 2878 this.analyticsEnabled = bool; 2879 } 2880 }, { 2881 key: "setEvents", 2882 value: function setEvents(events) { 2883 this.eventsEnabled = events; 2884 } 2885 }], [{ 2886 key: "allEvents", 2887 value: function allEvents() { 2888 return [RecrasEventHelper.EVENT_BOOKING_BOOKING_SUBMITTED, RecrasEventHelper.EVENT_BOOKING_CONTACT_FORM_SHOWN, RecrasEventHelper.EVENT_BOOKING_DATE_SELECTED, RecrasEventHelper.EVENT_BOOKING_PACKAGE_CHANGED, RecrasEventHelper.EVENT_BOOKING_PACKAGES_SHOWN, RecrasEventHelper.EVENT_BOOKING_PRODUCTS_SHOWN, RecrasEventHelper.EVENT_BOOKING_REDIRECT_PAYMENT, RecrasEventHelper.EVENT_BOOKING_RESET, RecrasEventHelper.EVENT_BOOKING_TIME_SELECTED, RecrasEventHelper.EVENT_CONTACT_FORM_SUBMIT, RecrasEventHelper.EVENT_VOUCHER_REDIRECT_PAYMENT, RecrasEventHelper.EVENT_VOUCHER_TEMPLATE_CHANGED, RecrasEventHelper.EVENT_VOUCHER_VOUCHER_SUBMITTED]; 2889 } 2890 }]); 2891 2892 return RecrasEventHelper; 2893}(); 2894 2895_defineProperty(RecrasEventHelper, "PREFIX_GLOBAL", 'Recras'); 2896 2897_defineProperty(RecrasEventHelper, "PREFIX_BOOKING", 'Booking'); 2898 2899_defineProperty(RecrasEventHelper, "PREFIX_CONTACT_FORM", 'ContactForm'); 2900 2901_defineProperty(RecrasEventHelper, "PREFIX_VOUCHER", 'Voucher'); 2902 2903_defineProperty(RecrasEventHelper, "EVENT_BOOKING_BOOKING_SUBMITTED", 'BuyInProgress'); 2904 2905_defineProperty(RecrasEventHelper, "EVENT_BOOKING_CONTACT_FORM_SHOWN", 'ContactFormShown'); 2906 2907_defineProperty(RecrasEventHelper, "EVENT_BOOKING_DATE_SELECTED", 'DateSelected'); 2908 2909_defineProperty(RecrasEventHelper, "EVENT_BOOKING_PACKAGE_CHANGED", 'PackageChanged'); 2910 2911_defineProperty(RecrasEventHelper, "EVENT_BOOKING_PACKAGES_SHOWN", 'PackagesShown'); 2912 2913_defineProperty(RecrasEventHelper, "EVENT_BOOKING_PRODUCTS_SHOWN", 'ProductsShown'); 2914 2915_defineProperty(RecrasEventHelper, "EVENT_BOOKING_REDIRECT_PAYMENT", 'RedirectToPayment'); 2916 2917_defineProperty(RecrasEventHelper, "EVENT_BOOKING_RESET", 'Reset'); 2918 2919_defineProperty(RecrasEventHelper, "EVENT_BOOKING_TIME_SELECTED", 'TimeSelected'); 2920 2921_defineProperty(RecrasEventHelper, "EVENT_CONTACT_FORM_SUBMIT", 'Submit'); 2922 2923_defineProperty(RecrasEventHelper, "EVENT_VOUCHER_REDIRECT_PAYMENT", 'RedirectToPayment'); 2924 2925_defineProperty(RecrasEventHelper, "EVENT_VOUCHER_TEMPLATE_CHANGED", 'TemplateChanged'); 2926 2927_defineProperty(RecrasEventHelper, "EVENT_VOUCHER_VOUCHER_SUBMITTED", 'BuyInProgress'); 2928 2929var RecrasHttpHelper = /*#__PURE__*/function () { 2930 function RecrasHttpHelper() { 2931 _classCallCheck(this, RecrasHttpHelper); 2932 } 2933 2934 _createClass(RecrasHttpHelper, null, [{ 2935 key: "call", 2936 value: function call(url, data, errorHandler) { 2937 if (!url) { 2938 throw new Error('ERR_FETCH_WITHOUT_URL'); //TODO: translate 2939 } 2940 2941 var lastResponse; 2942 return fetch(url, data).then(function (response) { 2943 lastResponse = response; 2944 return response.json(); 2945 }).then(function (json) { 2946 if (!lastResponse.ok) { 2947 var errorMsg = json.error && json.error.message ? json.error.message : lastResponse.status + ' ' + lastResponse.statusText; 2948 errorHandler(errorMsg); 2949 return false; 2950 } 2951 2952 return json; 2953 })["catch"](function (err) { 2954 errorHandler(err); 2955 }); 2956 } 2957 }, { 2958 key: "fetchJson", 2959 value: function fetchJson(url, errorHandler) { 2960 return this.call(url, { 2961 credentials: 'omit', 2962 method: 'get' 2963 }, errorHandler); 2964 } 2965 }, { 2966 key: "postJson", 2967 value: function postJson(url, data, errorHandler) { 2968 return this.call(url, { 2969 body: JSON.stringify(data), 2970 credentials: 'omit', 2971 method: 'post' 2972 }, errorHandler); 2973 } 2974 }]); 2975 2976 return RecrasHttpHelper; 2977}(); 2978 2979var RecrasLanguageHelper = /*#__PURE__*/function () { 2980 function RecrasLanguageHelper() { 2981 _classCallCheck(this, RecrasLanguageHelper); 2982 2983 this.defaultLocale = 'nl_NL'; 2984 this.locale = this.defaultLocale; 2985 this.options = null; //TODO: what is the best way to handle multiple locales? 2986 2987 this.i18n = { 2988 de_DE: { 2989 AGREE_ATTACHMENTS: 'Ich stimme den folgenden Unterlagen zu:', 2990 ATTR_REQUIRED: 'Erforderlich', 2991 BOOKING_DISABLED_AGREEMENT: 'Sie haben den Bedingungen noch nicht zugestimmt', 2992 BOOKING_DISABLED_AMOUNTS_INVALID: 'Programmbeträge sind ungültig',
2993 BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Das Kontaktformular ist nicht korrekt ausgefüllt', 2994 BOOKING_DISABLED_INVALID_DATE: 'Kein Datum ausgewählt', 2995 BOOKING_DISABLED_INVALID_TIME: 'Keine Zeit ausgewählt', 2996 BOOKING_DISABLED_REQUIRED_PRODUCT: 'Erforderliches Produkt noch nicht ausgewählt', 2997 BUTTON_BOOK_NOW: 'Jetzt buchen', 2998 BUTTON_BUY_NOW: 'Jetzt kaufen', 2999 BUTTON_SUBMIT_CONTACT_FORM: 'Senden', 3000 CONTACT_FORM_CHECKBOX_REQUIRED: 'Es muss mindestens eine Option aktiviert sein', 3001 CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" ist ungültig', 3002 CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" ist ein erforderliches Feld', 3003 CONTACT_FORM_SUBMIT_FAILED: 'Das Kontaktformular konnte nicht gesendet werden. Bitte versuchen Sie es später noch einmal.', 3004 CONTACT_FORM_SUBMIT_SUCCESS: 'Das Kontaktformular wurde erfolgreich gesendet.', 3005 DATE: 'Datum', 3006 DATE_FORMAT: 'TT-MM-JJJJ', 3007 DATE_INVALID: 'Ungültiges datum', 3008 DATE_PICKER_NEXT_MONTH: 'Nächsten Monat', 3009 DATE_PICKER_PREVIOUS_MONTH: 'Vorheriger Monat', 3010 DATE_PICKER_MONTH_JANUARY: 'Januar', 3011 DATE_PICKER_MONTH_FEBRUARY: 'Februar', 3012 DATE_PICKER_MONTH_MARCH: 'März', 3013 DATE_PICKER_MONTH_APRIL: 'April', 3014 DATE_PICKER_MONTH_MAY: 'Mai', 3015 DATE_PICKER_MONTH_JUNE: 'Juni', 3016 DATE_PICKER_MONTH_JULY: 'Juli', 3017 DATE_PICKER_MONTH_AUGUST: 'August', 3018 DATE_PICKER_MONTH_SEPTEMBER: 'September', 3019 DATE_PICKER_MONTH_OCTOBER: 'Oktober', 3020 DATE_PICKER_MONTH_NOVEMBER: 'November', 3021 DATE_PICKER_MONTH_DECEMBER: 'Dezember', 3022 DATE_PICKER_DAY_MONDAY_LONG: 'Montag', 3023 DATE_PICKER_DAY_MONDAY_SHORT: 'Mo', 3024 DATE_PICKER_DAY_TUESDAY_LONG: 'Dienstag', 3025 DATE_PICKER_DAY_TUESDAY_SHORT: 'Di', 3026 DATE_PICKER_DAY_WEDNESDAY_LONG: 'Mittwoch', 3027 DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Mi', 3028 DATE_PICKER_DAY_THURSDAY_LONG: 'Donnerstag', 3029 DATE_PICKER_DAY_THURSDAY_SHORT: 'Do', 3030 DATE_PICKER_DAY_FRIDAY_LONG: 'Freitag', 3031 DATE_PICKER_DAY_FRIDAY_SHORT: 'Fr', 3032 DATE_PICKER_DAY_SATURDAY_LONG: 'Samstag', 3033 DATE_PICKER_DAY_SATURDAY_SHORT: 'Sa', 3034 DATE_PICKER_DAY_SUNDAY_LONG: 'Sonntag', 3035 DATE_PICKER_DAY_SUNDAY_SHORT: 'So', 3036 DISCOUNT_APPLIED: 'Rabatt eingelöst', 3037 DISCOUNT_CHECK: 'Überprüfen', 3038 DISCOUNT_TITLE: 'Rabattcode oder Gutschein', 3039 DISCOUNT_INVALID: 'Ungültiger Rabattcode oder Gutschein', 3040 ERR_AMOUNTS_NO_PACKAGE: 'Die Option "productAmounts" ist gesetzt, aber "package_id" ist nicht gesetzt', 3041 ERR_CONTACT_FORM_EMPTY: 'Das Kontaktformular ist nicht ausgefüllt', 3042 ERR_DATE_NO_SINGLE_PACKAGE: 'Die Option "date" erfordert ein einzelnes vorgefülltes Arrangement ("package_id")', 3043 ERR_DATE_PAST: 'Option "date" ist ein Datum in der Vergangenheit', 3044 ERR_GENERAL: 'Etwas ist schief gelaufen:', 3045 ERR_INVALID_DATE: 'Die Option "date" ist keine gültige ISO 8601-Datumszeichenfolge (z. B. "2019-06-28")', 3046 ERR_INVALID_ELEMENT: 'Option "Element" ist kein gültiges Element', 3047 ERR_INVALID_HOSTNAME: 'Option "recras_hostname" ist ungültig.', 3048 ERR_INVALID_LOCALE: 'Ungültiges Gebietsschema. Gültige Optionen sind: {LOCALES}', 3049 ERR_INVALID_REDIRECT_URL: 'Ungültige redirect URL. Stellen Sie sicher, dass es mit http:// or https:// beginnt', 3050 ERR_INVALID_TIME: 'Die Option "time" ist keine gültige Zeitzeichenfolge (z. B. "16:15")', 3051 ERR_NO_ELEMENT: 'Option "element" nicht eingestellt.', 3052 ERR_NO_FORM: 'Option "form_id" nicht eingestellt.', 3053 ERR_NO_HOSTNAME: 'Option "recras_hostname" nicht eingestellt.', 3054 ERR_NO_TIMES_FOR_DATE: 'Für diese Mengen sind an diesem Datum keine Zeiten mehr verfügbar. Versuchen Sie es mit einem anderen Datum.', 3055 ERR_OPTIONS_INVALID: 'Options is not a "RecrasOptions" object', 3056 GENDER_UNKNOWN: 'Unbekannte', 3057 GENDER_MALE: 'Mann', 3058 GENDER_FEMALE: 'Frau', 3059 HEADING_PRICE: 'Preis', 3060 HEADING_QUANTITY: 'Anzahl', 3061 LOADING: 'Wird geladen...', 3062 NO_PRODUCTS: 'Kein Produkt ausgewählt', 3063 PRICE_TOTAL: 'Insgesamt', 3064 PRICE_TOTAL_WITH_DISCOUNT: 'Insgesamt inklusive Rabatt', 3065 PRODUCT_MAXIMUM: '(höchstens {MAXIMUM})', 3066 PRODUCT_MINIMUM: '(mindestens {MINIMUM})', 3067 PRODUCT_REQUIRED: '{NUM} {PRODUCT} benötigt {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} um auch gebucht zu werden.', 3068 TIME: 'Zeit', 3069 TIME_FORMAT: 'UU:MM', 3070 VOUCHER_ALREADY_APPLIED: 'Gutschein bereits eingelöst', 3071 VOUCHER_APPLIED: 'Gutschein eingelöst', 3072 VOUCHER_EMPTY: 'Leerer Gutscheincode',
3073 VOUCHER_QUANTITY: 'Anzahl der Gutscheine', 3074 VOUCHERS_DISCOUNT: 'Rabatt von Gutschein(en)' 3075 }, 3076 en_GB: { 3077 AGREE_ATTACHMENTS: 'I agree with the following documents:', 3078 ATTR_REQUIRED: 'Required', 3079 BOOKING_DISABLED_AGREEMENT: 'You have not agreed to the terms yet', 3080 BOOKING_DISABLED_AMOUNTS_INVALID: 'Programme amounts are invalid', 3081 BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Contact form is not filled in correctly', 3082 BOOKING_DISABLED_INVALID_DATE: 'No date selected', 3083 BOOKING_DISABLED_INVALID_TIME: 'No time selected', 3084 BOOKING_DISABLED_REQUIRED_PRODUCT: 'Required product not yet selected', 3085 BUTTON_BOOK_NOW: 'Book now', 3086 BUTTON_BUY_NOW: 'Buy now', 3087 BUTTON_SUBMIT_CONTACT_FORM: 'Submit', 3088 CONTACT_FORM_CHECKBOX_REQUIRED: 'At least one option must be checked', 3089 CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" is invalid', 3090 CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" is a required field', 3091 CONTACT_FORM_SUBMIT_FAILED: 'The contact form could not be sent. Please try again later.', 3092 CONTACT_FORM_SUBMIT_SUCCESS: 'The contact form was sent successfully.', 3093 DATE: 'Date', 3094 DATE_FORMAT: 'DD-MM-YYYY', 3095 DATE_INVALID: 'Invalid date', 3096 DATE_PICKER_NEXT_MONTH: 'Next month', 3097 DATE_PICKER_PREVIOUS_MONTH: 'Previous month', 3098 DATE_PICKER_MONTH_JANUARY: 'January', 3099 DATE_PICKER_MONTH_FEBRUARY: 'February', 3100 DATE_PICKER_MONTH_MARCH: 'March', 3101 DATE_PICKER_MONTH_APRIL: 'April', 3102 DATE_PICKER_MONTH_MAY: 'May', 3103 DATE_PICKER_MONTH_JUNE: 'June', 3104 DATE_PICKER_MONTH_JULY: 'July', 3105 DATE_PICKER_MONTH_AUGUST: 'August', 3106 DATE_PICKER_MONTH_SEPTEMBER: 'September', 3107 DATE_PICKER_MONTH_OCTOBER: 'October', 3108 DATE_PICKER_MONTH_NOVEMBER: 'November', 3109 DATE_PICKER_MONTH_DECEMBER: 'December', 3110 DATE_PICKER_DAY_MONDAY_LONG: 'Monday', 3111 DATE_PICKER_DAY_MONDAY_SHORT: 'Mon', 3112 DATE_PICKER_DAY_TUESDAY_LONG: 'Tuesday', 3113 DATE_PICKER_DAY_TUESDAY_SHORT: 'Tue', 3114 DATE_PICKER_DAY_WEDNESDAY_LONG: 'Wednesday', 3115 DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Wed', 3116 DATE_PICKER_DAY_THURSDAY_LONG: 'Thursday', 3117 DATE_PICKER_DAY_THURSDAY_SHORT: 'Thu', 3118 DATE_PICKER_DAY_FRIDAY_LONG: 'Friday', 3119 DATE_PICKER_DAY_FRIDAY_SHORT: 'Fri', 3120 DATE_PICKER_DAY_SATURDAY_LONG: 'Saturday', 3121 DATE_PICKER_DAY_SATURDAY_SHORT: 'Sat', 3122 DATE_PICKER_DAY_SUNDAY_LONG: 'Sunday', 3123 DATE_PICKER_DAY_SUNDAY_SHORT: 'Sun', 3124 DISCOUNT_APPLIED: 'Discount applied', 3125 DISCOUNT_CHECK: 'Check', 3126 DISCOUNT_TITLE: 'Discount code or voucher', 3127 DISCOUNT_INVALID: 'Invalid discount code or voucher', 3128 ERR_AMOUNTS_NO_PACKAGE: 'Option "productAmounts" is set, but "package_id" is not set', 3129 ERR_CONTACT_FORM_EMPTY: 'Contact form is not filled in', 3130 ERR_DATE_NO_SINGLE_PACKAGE: 'Option "date" requires a single pre-filled package ("package_id")', 3131 ERR_DATE_PAST: 'Option "date" is a date in the past', 3132 ERR_GENERAL: 'Something went wrong:', 3133 ERR_INVALID_DATE: 'Option "date" is not a valid ISO 8601 date string (e.g. "2019-06-28")', 3134 ERR_INVALID_ELEMENT: 'Option "element" is not a valid Element', 3135 ERR_INVALID_HOSTNAME: 'Option "recras_hostname" is invalid.', 3136 ERR_INVALID_LOCALE: 'Invalid locale. Valid options are: {LOCALES}', 3137 ERR_INVALID_REDIRECT_URL: 'Invalid redirect URL. Make sure you it starts with http:// or https://', 3138 ERR_INVALID_TIME: 'Option "time" is not a valid time string (e.g. "16:15")', 3139 ERR_NO_ELEMENT: 'Option "element" not set.', 3140 ERR_NO_FORM: 'Option "form_id" not set.', 3141 ERR_NO_HOSTNAME: 'Option "recras_hostname" not set.', 3142 ERR_NO_TIMES_FOR_DATE: 'There are no more times available on this date for these quantities. Try a different date.', 3143 ERR_OPTIONS_INVALID: 'Options is not a "RecrasOptions" object', 3144 GENDER_UNKNOWN: 'Unknown', 3145 GENDER_MALE: 'Male', 3146 GENDER_FEMALE: 'Female', 3147 HEADING_PRICE: 'Price', 3148 HEADING_QUANTITY: 'Quantity', 3149 LOADING: 'Loading...', 3150 NO_PRODUCTS: 'No product selected', 3151 PRICE_TOTAL: 'Total', 3152 PRICE_TOTAL_WITH_DISCOUNT: 'Total including discount', 3153 PRODUCT_MAXIMUM: '(at most {MAXIMUM})',
3154 PRODUCT_MINIMUM: '(at least {MINIMUM})', 3155 PRODUCT_REQUIRED: '{NUM} {PRODUCT} requires {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} to also be booked.', 3156 TIME: 'Time', 3157 TIME_FORMAT: 'HH:MM', 3158 VOUCHER_ALREADY_APPLIED: 'Voucher already applied', 3159 VOUCHER_APPLIED: 'Voucher applied', 3160 VOUCHER_EMPTY: 'Empty voucher code', 3161 VOUCHER_QUANTITY: 'Number of vouchers', 3162 VOUCHERS_DISCOUNT: 'Discount from voucher(s)' 3163 }, 3164 nl_NL: { 3165 AGREE_ATTACHMENTS: 'Ik ga akkoord met de volgende gegevens:', 3166 ATTR_REQUIRED: 'Vereist', 3167 BOOKING_DISABLED_AGREEMENT: 'Je bent nog niet akkoord met de voorwaarden', 3168 BOOKING_DISABLED_AMOUNTS_INVALID: 'Aantallen in programma zijn ongeldig', 3169 BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Contactformulier is niet correct ingevuld', 3170 BOOKING_DISABLED_INVALID_DATE: 'Geen datum geselecteerd', 3171 BOOKING_DISABLED_INVALID_TIME: 'Geen tijd geselecteerd', 3172 BOOKING_DISABLED_REQUIRED_PRODUCT: 'Vereist product nog niet geselecteerd', 3173 BUTTON_BOOK_NOW: 'Nu boeken', 3174 BUTTON_BUY_NOW: 'Nu kopen', 3175 BUTTON_SUBMIT_CONTACT_FORM: 'Versturen', 3176 CONTACT_FORM_CHECKBOX_REQUIRED: 'Ten minste één optie moet aangevinkt worden', 3177 CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" is ongeldig', 3178 CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" is een verplicht veld', 3179 CONTACT_FORM_SUBMIT_FAILED: 'Het contactformulier kon niet worden verstuurd. Probeer het later nog eens.', 3180 CONTACT_FORM_SUBMIT_SUCCESS: 'Het contactformulier is succesvol verstuurd.', 3181 DATE: 'Datum', 3182 DATE_FORMAT: 'DD-MM-JJJJ', 3183 DATE_INVALID: 'Ongeldige datum', 3184 DATE_PICKER_NEXT_MONTH: 'Volgende maand', 3185 DATE_PICKER_PREVIOUS_MONTH: 'Vorige maand', 3186 DATE_PICKER_MONTH_JANUARY: 'Januari', 3187 DATE_PICKER_MONTH_FEBRUARY: 'Februari', 3188 DATE_PICKER_MONTH_MARCH: 'Maart', 3189 DATE_PICKER_MONTH_APRIL: 'April', 3190 DATE_PICKER_MONTH_MAY: 'Mei', 3191 DATE_PICKER_MONTH_JUNE: 'Juni', 3192 DATE_PICKER_MONTH_JULY: 'Juli', 3193 DATE_PICKER_MONTH_AUGUST: 'Augustus', 3194 DATE_PICKER_MONTH_SEPTEMBER: 'September', 3195 DATE_PICKER_MONTH_OCTOBER: 'Oktober', 3196 DATE_PICKER_MONTH_NOVEMBER: 'November', 3197 DATE_PICKER_MONTH_DECEMBER: 'December', 3198 DATE_PICKER_DAY_MONDAY_LONG: 'Maandag', 3199 DATE_PICKER_DAY_MONDAY_SHORT: 'Ma', 3200 DATE_PICKER_DAY_TUESDAY_LONG: 'Dinsdag', 3201 DATE_PICKER_DAY_TUESDAY_SHORT: 'Di', 3202 DATE_PICKER_DAY_WEDNESDAY_LONG: 'Woensdag', 3203 DATE_PICKER_DAY_WEDNESDAY_SHORT: 'Wo', 3204 DATE_PICKER_DAY_THURSDAY_LONG: 'Donderdag', 3205 DATE_PICKER_DAY_THURSDAY_SHORT: 'Do', 3206 DATE_PICKER_DAY_FRIDAY_LONG: 'Vrijdag', 3207 DATE_PICKER_DAY_FRIDAY_SHORT: 'Vr', 3208 DATE_PICKER_DAY_SATURDAY_LONG: 'Zaterdag', 3209 DATE_PICKER_DAY_SATURDAY_SHORT: 'Za', 3210 DATE_PICKER_DAY_SUNDAY_LONG: 'Zondag', 3211 DATE_PICKER_DAY_SUNDAY_SHORT: 'Zo', 3212 DISCOUNT_APPLIED: 'Kortingscode toegepast', 3213 DISCOUNT_CHECK: 'Controleren', 3214 DISCOUNT_TITLE: 'Kortingscode of tegoedbon', 3215 DISCOUNT_INVALID: 'Ongeldige kortingscode of tegoedbon', 3216 ERR_AMOUNTS_NO_PACKAGE: 'Optie "productAmounts" is ingesteld, maar "package_id" is niet ingesteld', 3217 ERR_CONTACT_FORM_EMPTY: 'Contactformulier is niet ingevuld', 3218 ERR_DATE_NO_SINGLE_PACKAGE: 'Optie "date" vereist een enkel vooraf ingevuld arrangement ("package_id")', 3219 ERR_DATE_PAST: 'Optie "date" is een datum in het verleden', 3220 ERR_GENERAL: 'Er ging iets mis:', 3221 ERR_INVALID_DATE: 'Optie "date" is geen geldige ISO 8601-datumstring (bijv. "2019-06-28")', 3222 ERR_INVALID_ELEMENT: 'Optie "element" is geen geldig Element', 3223 ERR_INVALID_HOSTNAME: 'Optie "recras_hostname" is ongeldig.', 3224 ERR_INVALID_LOCALE: 'Ongeldige locale. Geldige opties zijn: {LOCALES}', 3225 ERR_INVALID_REDIRECT_URL: 'Ongeldige redirect-URL. Zorg ervoor dat deze begint met http:// of https://', 3226 ERR_INVALID_TIME: 'Optie "time" is geen geldige tijd-string (bijv. "16:15")', 3227 ERR_NO_ELEMENT: 'Optie "element" niet ingesteld.', 3228 ERR_NO_FORM: 'Optie "form_id" niet ingesteld.', 3229 ERR_NO_HOSTNAME: 'Optie "recras_hostname" niet ingesteld.', 3230 ERR_NO_TIMES_FOR_DATE: 'Er zijn geen tijden meer beschikbaar op deze datum voor deze aantallen. Probeer een andere datum.', 3231 ERR_OPTIONS_INVALID: 'Opties is geen "RecrasOptions"-object', 3232 GENDER_UNKNOWN: 'Onbekend', 3233 GENDER_MALE: 'Man', 3234 GENDER_FEMALE: 'Vrouw', 3235 HEADING_PRICE: 'Prijs', 3236 HEADING_QUANTITY: 'Aantal', 3237 LOADING: 'Laden...', 3238 NO_PRODUCTS: 'Geen product gekozen', 3239 PRICE_TOTAL: 'Totaal', 3240 PRICE_TOTAL_WITH_DISCOUNT: 'Totaal inclusief korting', 3241 PRODUCT_MAXIMUM: '(maximaal {MAXIMUM})', 3242 PRODUCT_MINIMUM: '(minimaal {MINIMUM})', 3243 PRODUCT_REQUIRED: '{NUM} {PRODUCT} vereist dat ook {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} geboekt wordt.', 3244 TIME: 'Tijd', 3245 TIME_FORMAT: 'UU:MM', 3246 VOUCHER_ALREADY_APPLIED: 'Tegoedbon al toegepast', 3247 VOUCHER_APPLIED: 'Tegoedbon toegepast', 3248 VOUCHER_EMPTY: 'Lege tegoedbon', 3249 VOUCHER_QUANTITY: 'Aantal tegoedbonnen', 3250 VOUCHERS_DISCOUNT: 'Korting uit tegoedbon(nen)' 3251 }, 3252 sv_SE: { 3253 AGREE_ATTACHMENTS: 'Jag håller med följande information:', 3254 ATTR_REQUIRED: "Obligatoriskt", 3255 BOOKING_DISABLED_AGREEMENT: 'Du håller inte med villkoren ännu', 3256 BOOKING_DISABLED_AMOUNTS_INVALID: 'Siffrorna i programmet är ogiltiga',
3257 BOOKING_DISABLED_CONTACT_FORM_INVALID: 'Kontaktformuläret är inte korrekt ifyllt', 3258 BOOKING_DISABLED_INVALID_DATE: 'Inget datum valt', 3259 BOOKING_DISABLED_INVALID_TIME: 'Ingen tid vald', 3260 BOOKING_DISABLED_REQUIRED_PRODUCT: "Nödvändig produkt har ännu inte valts", 3261 BUTTON_BOOK_NOW: 'Boka nu', 3262 BUTTON_BUY_NOW: 'Köp nu', 3263 BUTTON_SUBMIT_CONTACT_FORM: 'Skicka', 3264 CONTACT_FORM_CHECKBOX_REQUIRED: 'Minst ett alternativ måste markeras', 3265 CONTACT_FORM_FIELD_INVALID: '"{FIELD_NAME}" är ogiltig', 3266 CONTACT_FORM_FIELD_REQUIRED: '"{FIELD_NAME}" är ett obligatoriskt fält', 3267 CONTACT_FORM_SUBMIT_FAILED: 'Kontaktformuläret kunde inte skickas. Vänligen försök igen senare.', 3268 CONTACT_FORM_SUBMIT_SUCCESS: 'Kontaktformuläret har skickats.', 3269 DATUM: 'Datum', 3270 DATE_FORMAT: 'DD-MM-ÅÅÅÅ', 3271 DATE_INVALID: "Ogiltigt datum", 3272 DATE_PICKER_NEXT_MONTH: "Nästa månad", 3273 DATE_PICKER_PREVIOUS_MONTH: "Förra månaden", 3274 DATE_PICKER_MONTH_JANUARI: "januari", 3275 DATE_PICKER_MONTH_FEBRUARY: "februari", 3276 DATE_PICKER_MONTH_MARCH: "mars", 3277 DATE_PICKER_MONTH_APRIL: "april", 3278 DATE_PICKER_MONTH_MAY: "aaj", 3279 DATE_PICKER_MONTH_JUNE: "juni", 3280 DATE_PICKER_MONTH_JULY: "Juli", 3281 DATE_PICKER_MONTH_AUGUST: "augusti", 3282 DATE_PICKER_MONTH_SEPTEMBER: "september", 3283 DATE_PICKER_MONTH_OCTOBER: "oktober", 3284 DATE_PICKER_MONTH_NOVEMBER: "november", 3285 DATE_PICKER_MONTH_DECEMBER: "december", 3286 DATE_PICKER_DAY_MONDAY_LONG: "Måndag", 3287 DATE_PICKER_DAY_MONDAY_SHORT: 'Mån', 3288 DATE_PICKER_DAY_TUESDAY_LONG: "Tisdag", 3289 DATE_PICKER_DAY_TUESDAY_SHORT: 'Tis', 3290 DATE_PICKER_DAY_WEDNESDAY_LONG: "Onsdag", 3291 DATE_PICKER_DAY_WEDNESDAY_SHORT: "Ons", 3292 DATE_PICKER_DAY_THURSDAY_LONG: "Torsdag", 3293 DATE_PICKER_DAY_THURSDAY_SHORT: "Tors", 3294 DATE_PICKER_DAY_FRIDAY_LONG: "Fredag", 3295 DATE_PICKER_DAY_FRIDAY_SHORT: "Fre", 3296 DATE_PICKER_DAY_SATURDAY_LONG: 'Lördag', 3297 DATE_PICKER_DAY_SATURDAY_SHORT: 'Lör', 3298 DATE_PICKER_DAY_SUNDAY_LONG: "Söndag", 3299 DATE_PICKER_DAY_SUNDAY_SHORT: "Sön", 3300 DISCOUNT_APPLIED: 'Rabattkod tillämpas', 3301 DISCOUNT_CHECK: "Kontrollera", 3302 DISCOUNT_TITLE: "Rabattkod eller kupong", 3303 DISCOUNT_INVALID: "Ogiltig rabattkod eller kupong", 3304 ERR_AMOUNTS_NO_PACKAGE: 'Alternativ "productAmounts" är inställt, men "package_id" är inte inställt', 3305 ERR_CONTACT_FORM_EMPTY: 'Kontaktformuläret är inte ifyllt', 3306 ERR_DATE_NO_SINGLE_PACKAGE: 'Alternativ "date" kräver ett enda förfyllt paket ("package_id")', 3307 ERR_DATE_PAST: 'Alternativ "date" är ett datum tidigare', 3308 ERR_GENERAL: 'Något gick fel:', 3309 ERR_INVALID_DATE: 'Alternativ "date" är inte en giltig ISO 8601-datumsträng (t.ex. "2019-06-28")', 3310 ERR_INVALID_ELEMENT: 'Alternativet "element" är inte ett giltigt element', 3311 ERR_INVALID_HOSTNAME: 'Alternativet "recras_hostname" är ogiltigt.', 3312 ERR_INVALID_LOCALE: 'Ogiltig land-språkkombination. Giltiga alternativ är: {LOCALES} ', 3313 ERR_INVALID_REDIRECT_URL: 'Ogiltig omdirigerings-URL. Se till att det börjar med http:// eller https:// ', 3314 ERR_INVALID_TIME: 'Alternativ "time" är inte en giltig tidsnotation (t.ex. "16:15")', 3315 ERR_NO_ELEMENT: 'Alternativet "element" är inte inställt.', 3316 ERR_NO_FORM: 'Alternativ "form_id" inte inställt.', 3317 ERR_NO_HOSTNAME: 'Alternativ "recras_hostname" inte inställt.', 3318 ERR_NO_TIMES_FOR_DATE: 'Det finns inga fler tillgängliga tider på detta datum för dessa nummer. Prova ett annat datum. ', 3319 ERR_OPTIONS_INVALID: 'Alternativ är inte ett "RecrasOptions"-objekt', 3320 GENDER_UNKNOWN: "Okänd", 3321 GENDER_MALE: "Man", 3322 GENDER_FEMALE: "Kvinna", 3323 HEADING_PRICE: "Pris", 3324 HEADING_QUANTITY: "Antal", 3325 LOADING: 'Laddar ...', 3326 NO_PRODUCTS: 'Ingen produkt vald', 3327 PRICE_TOTAL: 'Totalt', 3328 PRICE_TOTAL_WITH_DISCOUNT: "Totalt inklusive rabatt", 3329 PRODUCT_MAXIMUM: '(maximalt {MAXIMUM})', 3330 PRODUCT_MINIMUM: '(minimalt {MINIMUM})', 3331 PRODUCT_REQUIRED: '{NUM} {PRODUCT} kräver att {REQUIRED_AMOUNT} {REQUIRED_PRODUCT} också bokas.', 3332 TIME: 'Tid', 3333 TIME_FORMAT: 'TT:MM', 3334 VOUCHER_ALREADY_APPLIED: 'Kupongen är redan inlöst', 3335 VOUCHER_APPLIED: 'Kupong inlöst', 3336 VOUCHER_EMPTY: "Tom kupong", 3337 VOUCHER_QUANTITY: 'Antal kuponger', 3338 VOUCHERS_DISCOUNT: 'Rabatt från kupong(er)' 3339 } 3340 }; 3341 } 3342 3343 _createClass(RecrasLanguageHelper, [{ 3344 key: "error", 3345 value: function error(msg) { 3346 console.log('Error', msg); //TODO 3347 } 3348 }, {
3349 key: "extractTags", 3350 value: function extractTags(msg) { 3351 var alphanumericWithUnderscore = '[a-zA-Z0-9_]'; 3352 var regexPartMulticolumn = '((?:\\((?:\\w+)(?::[^)]*)?\\))*)'; 3353 var regex = new RegExp('{' + alphanumericWithUnderscore + '+' + regexPartMulticolumn + '}', 'g'); 3354 var tags = msg.match(regex); 3355 3356 if (!Array.isArray(tags)) { 3357 return []; 3358 } 3359 3360 return tags.map(function (tag) { 3361 return tag.substring(1, tag.length - 1); 3362 }); // Strip { and } 3363 } 3364 }, { 3365 key: "filterTags", 3366 value: function filterTags(msg, packageID) { 3367 var tags = this.extractTags(msg); 3368 3369 if (tags.length === 0) { 3370 return Promise.resolve(msg); 3371 } 3372 3373 return RecrasHttpHelper.postJson(this.options.getApiBase() + 'tagfilter', { 3374 tags: tags, 3375 context: { 3376 packageID: packageID 3377 } 3378 }, this.error).then(function (filtered) { 3379 Object.keys(filtered).forEach(function (tag) { 3380 msg = msg.split('{' + tag + '}').join(filtered[tag]); 3381 }); 3382 return msg; 3383 }); 3384 } 3385 }, { 3386 key: "formatLocale", 3387 value: function formatLocale(what) { 3388 switch (what) { 3389 case 'currency': 3390 return this.locale.replace('_', '-').toUpperCase(); 3391 3392 default: 3393 return this.locale; 3394 } 3395 } 3396 }, { 3397 key: "formatPrice", 3398 value: function formatPrice(price) { 3399 return parseFloat(price).toLocaleString(this.formatLocale('currency'), { 3400 currency: this.currency, 3401 style: 'currency' 3402 }); 3403 } 3404 }, { 3405 key: "setCurrency", 3406 value: function setCurrency() { 3407 var _this40 = this; 3408 3409 var errorHandler = function errorHandler(err) { 3410 _this40.currency = 'eur'; 3411 3412 _this40.error(err); 3413 }; 3414 3415 return RecrasHttpHelper.fetchJson(this.options.getApiBase() + 'instellingen/currency', errorHandler).then(function (setting) { 3416 _this40.currency = setting.waarde; 3417 }); 3418 } 3419 }, { 3420 key: "setLocale", 3421 value: function setLocale(locale) { 3422 this.locale = locale; 3423 } 3424 }, { 3425 key: "setOptions", 3426 value: function setOptions(options) { 3427 this.options = options; 3428 return this.setCurrency(); 3429 } 3430 }, { 3431 key: "translate", 3432 value: function translate(string) { 3433 var vars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3434 var translated; 3435 3436 if (this.i18n[this.locale] && this.i18n[this.locale][string]) { 3437 translated = this.i18n[this.locale][string]; 3438 } else if (this.i18n.en_GB[string]) { 3439 translated = this.i18n.en_GB[string]; 3440 } else { 3441 translated = string; 3442 console.warn('String not translated: ' + string); 3443 } 3444 3445 if (Object.keys(vars).length > 0) { 3446 Object.keys(vars).forEach(function (key) { 3447 translated = translated.replace('{' + key + '}', vars[key]); 3448 }); 3449 } 3450 3451 return translated; 3452 } 3453 }], [{ 3454 key: "isValid", 3455 value: function isValid(locale) { 3456 return this.validLocales.indexOf(locale) > -1; 3457 } 3458 }]); 3459 3460 return RecrasLanguageHelper; 3461}(); 3462 3463_defineProperty(RecrasLanguageHelper, "validLocales", ['de_DE', 'en_GB', 'nl_NL', 'sv_SE']); 3464 3465var RecrasOptions = /*#__PURE__*/function () { 3466 function RecrasOptions(options) { 3467 _classCallCheck(this, RecrasOptions); 3468 3469 this.languageHelper = new RecrasLanguageHelper(); 3470 this.validate(options); 3471 this.options = this.setOptions(options); 3472 } 3473 3474 _createClass(RecrasOptions, [{ 3475 key: "getAnalyticsEvents", 3476 value: function getAnalyticsEvents() { 3477 if (!Array.isArray(this.options.analyticsEvents)) { 3478 this.options.analyticsEvents = RecrasEventHelper.allEvents(); 3479 } 3480 3481 this.options.analyticsEvents = this.options.analyticsEvents.filter(function (event) { 3482 var eventExists = RecrasEventHelper.allEvents().includes(event); 3483 3484 if (!eventExists) { 3485 console.warn('Invalid event: ' + event); 3486 } 3487 3488 return eventExists; 3489 }); 3490 3491 if (this.options.analyticsEvents.length === 0) { 3492 this.options.analyticsEvents = RecrasEventHelper.allEvents(); 3493 } 3494 3495 return this.options.analyticsEvents; 3496 } 3497 }, {
3498 key: "getAnalytics", 3499 value: function getAnalytics() { 3500 return this.options.analytics; 3501 } 3502 }, { 3503 key: "getApiBase", 3504 value: function getApiBase() { 3505 return this.getHostname() + '/api2/'; 3506 } 3507 }, { 3508 key: "getAutoScroll", 3509 value: function getAutoScroll() { 3510 return this.options.autoScroll !== undefined ? this.options.autoScroll : true; 3511 } 3512 }, { 3513 key: "getDefaultCountry", 3514 value: function getDefaultCountry() { 3515 if (this.options.defaultCountry !== undefined) { 3516 return this.options.defaultCountry; 3517 } 3518 3519 return this.getLocale().substr(3, 2); // en_IE -> IE 3520 } 3521 }, { 3522 key: "getElement", 3523 value: function getElement() { 3524 return this.options.element; 3525 } 3526 }, { 3527 key: "getFormId", 3528 value: function getFormId() { 3529 return this.options.form_id; 3530 } 3531 }, { 3532 key: "getHostname", 3533 value: function getHostname() { 3534 return this.options.hostname; 3535 } 3536 }, { 3537 key: "getLocale", 3538 value: function getLocale() { 3539 return this.options.locale; 3540 } 3541 }, { 3542 key: "getPackageId", 3543 value: function getPackageId() { 3544 return this.options.package_id; 3545 } 3546 }, { 3547 key: "getPreFilledAmounts", 3548 value: function getPreFilledAmounts() { 3549 return this.options.productAmounts; 3550 } 3551 }, { 3552 key: "getPreFilledDate", 3553 value: function getPreFilledDate() { 3554 return this.options.date; 3555 } 3556 }, { 3557 key: "getPreFilledTime", 3558 value: function getPreFilledTime() { 3559 return this.options.time; 3560 } 3561 }, { 3562 key: "getPreviewTimes", 3563 value: function getPreviewTimes() { 3564 return this.options.previewTimes !== undefined ? this.options.previewTimes : true; 3565 } 3566 }, { 3567 key: "getRedirectUrl", 3568 value: function getRedirectUrl() { 3569 return this.options.redirect_url; 3570 } 3571 }, { 3572 key: "getVoucherTemplateId", 3573 value: function getVoucherTemplateId() { 3574 return this.options.voucher_template_id; 3575 } 3576 }, { 3577 key: "isSinglePackage", 3578 value: function isSinglePackage() { 3579 if (Array.isArray(this.options.package_id)) { 3580 return this.options.package_id.length === 1; 3581 } 3582 3583 return !isNaN(parseInt(this.options.package_id, 10)); 3584 } 3585 }, { 3586 key: "setOption", 3587 value: function setOption(option, value) { 3588 this.options[option] = value; 3589 } 3590 }, { 3591 key: "setOptions", 3592 value: function setOptions(options) { 3593 var protocol = 'https'; 3594 3595 if (RecrasOptions.hostnamesDebug.includes(options.recras_hostname)) { 3596 protocol = 'http'; 3597 } 3598 3599 options.hostname = protocol + '://' + options.recras_hostname; 3600 return options; 3601 } 3602 }, { 3603 key: "validate", 3604 value: function validate(options) { 3605 var hostnameRegex = new RegExp(/^[a-z0-9\-]+\.recras\.nl$/i); 3606 3607 if (!options.element) { 3608 throw new Error(this.languageHelper.translate('ERR_NO_ELEMENT')); 3609 } 3610 3611 if (options.element instanceof Element === false) { 3612 throw new Error(this.languageHelper.translate('ERR_INVALID_ELEMENT')); 3613 } 3614 3615 if (!options.recras_hostname) { 3616 throw new Error(this.languageHelper.translate('ERR_NO_HOSTNAME')); 3617 } 3618 3619 if (!hostnameRegex.test(options.recras_hostname) && !RecrasOptions.hostnamesDebug.includes(options.recras_hostname)) { 3620 throw new Error(this.languageHelper.translate('ERR_INVALID_HOSTNAME')); 3621 } 3622 3623 if (options.redirect_url) { 3624 if (options.redirect_url.indexOf('http://') === -1 && options.redirect_url.indexOf('https://') === -1) { 3625 throw new Error(this.languageHelper.translate('ERR_INVALID_REDIRECT_URL')); 3626 } 3627 } 3628 } 3629 }]); 3630 3631 return RecrasOptions; 3632}(); 3633 3634_defineProperty(RecrasOptions, "hostnamesDebug", ['nginx:8886', // Local development 3635 'nginx' // Docker Selenium tests 3636]); 3637 3638var RecrasVoucher = /*#__PURE__*/function () { 3639 function RecrasVoucher() { 3640 var _this41 = this; 3641 3642 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 3643 3644 _classCallCheck(this, RecrasVoucher); 3645 3646 this.languageHelper = new RecrasLanguageHelper(); 3647 3648 if (options instanceof RecrasOptions === false) { 3649 throw new Error(this.languageHelper.translate('ERR_OPTIONS_INVALID')); 3650 } 3651 3652 this.options = options; 3653 this.eventHelper = new RecrasEventHelper(); 3654 this.eventHelper.setEvents(this.options.getAnalyticsEvents()); 3655 this.element = this.options.getElement(); 3656 this.element.classList.add('recras-buy-voucher'); 3657 3658 this.fetchJson = function (url) { 3659 return RecrasHttpHelper.fetchJson(url, _this41.error); 3660 }; 3661 3662 this.postJson = function (url, data) { 3663 return RecrasHttpHelper.postJson(_this41.options.getApiBase() + url, data, _this41.error); 3664 }; 3665 3666 RecrasCSSHelper.loadCSS('global'); 3667 3668 if (this.options.getLocale()) { 3669 if (!RecrasLanguageHelper.isValid(this.options.getLocale())) { 3670 console.warn(this.languageHelper.translate('ERR_INVALID_LOCALE', { 3671 LOCALES: RecrasLanguageHelper.validLocales.join(', ') 3672 })); 3673 } else { 3674 this.languageHelper.setLocale(this.options.getLocale()); 3675 } 3676 } 3677 3678 this.languageHelper.setOptions(options).then(function () { 3679 return _this41.getVoucherTemplates(); 3680 }).then(function (templates) { 3681 if (_this41.options.getVoucherTemplateId()) { 3682 _this41.changeTemplate(_this41.options.getVoucherTemplateId()); 3683 } else { 3684 _this41.showTemplates(templates); 3685 } 3686 }); 3687 } 3688 3689 _createClass(RecrasVoucher, [{ 3690 key: "appendHtml", 3691 value: function appendHtml(msg) { 3692 this.element.insertAdjacentHTML('beforeend', msg); 3693 } 3694 }, {
3695 key: "formatGA4Item", 3696 value: function formatGA4Item() { 3697 return [{ 3698 item_name: this.selectedTemplate.name, 3699 price: this.selectedTemplate.price, 3700 quantity: parseInt(this.findElement('#number-of-vouchers').value) 3701 }]; 3702 } 3703 }, { 3704 key: "buyTemplate", 3705 value: function buyTemplate() { 3706 var _this42 = this; 3707 3708 var status = this.contactForm.checkRequiredCheckboxes(); 3709 3710 if (!status) { 3711 return false; 3712 } 3713 3714 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_VOUCHER_SUBMITTED, this.selectedTemplate.name, Math.round(this.totalPrice())); 3715 this.findElement('.buyTemplate').setAttribute('disabled', 'disabled'); 3716 var payload = { 3717 voucher_template_id: this.selectedTemplate.id, 3718 number_of_vouchers: parseInt(this.findElement('.number-of-vouchers').value, 10), 3719 contact_form: this.contactForm.generateJson() 3720 }; 3721 3722 if (this.options.getRedirectUrl()) { 3723 payload.redirect_url = this.options.getRedirectUrl(); 3724 } 3725 3726 this.postJson('vouchers/buy', payload).then(function (json) { 3727 if (json.payment_url) { 3728 _this42.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_REDIRECT_PAYMENT, null, Math.round(_this42.totalPrice()), { 3729 currency: _this42.languageHelper.currency, 3730 value: _this42.totalPrice(), 3731 items: _this42.formatGA4Item() 3732 }); 3733 3734 window.top.location.href = json.payment_url; 3735 } else { 3736 console.log(json); 3737 } 3738 3739 _this42.findElement('.buyTemplate').removeAttribute('disabled'); 3740 }); 3741 } 3742 }, { 3743 key: "changeTemplate", 3744 value: function changeTemplate(templateID) { 3745 this.selectedTemplate = this.templates.filter(function (t) { 3746 return t.id === templateID; 3747 })[0]; 3748 this.clearAllExceptTemplateSelection(); 3749 this.showContactForm(this.selectedTemplate); 3750 this.eventHelper.sendEvent(RecrasEventHelper.PREFIX_VOUCHER, RecrasEventHelper.EVENT_VOUCHER_TEMPLATE_CHANGED, null, templateID, { 3751 content_type: 'voucher', 3752 item_id: templateID 3753 }); 3754 } 3755 }, { 3756 key: "clearAll", 3757 value: function clearAll() { 3758 this.clearElements(this.element.children); 3759 } 3760 }, { 3761 key: "clearAllExceptTemplateSelection", 3762 value: function clearAllExceptTemplateSelection() { 3763 var elements = document.querySelectorAll('#' + this.element.id + ' > *:not(.recras-voucher-templates)'); 3764 this.clearElements(elements); 3765 } 3766 }, { 3767 key: "clearElements", 3768 value: function clearElements(elements) { 3769 _toConsumableArray(elements).forEach(function (el) { 3770 el.parentNode.removeChild(el); 3771 }); 3772 3773 this.maybeAddLatestErrorElement(); 3774 } 3775 }, { 3776 key: "error", 3777 value: function error(msg) { 3778 this.maybeAddLatestErrorElement(); 3779 this.findElement('.latestError').innerHTML = "<strong>".concat(this.languageHelper.translate('ERR_GENERAL'), "</strong><p>").concat(msg, "</p>"); 3780 } 3781 }, { 3782 key: "findElement", 3783 value: function findElement(querystring) { 3784 return this.element.querySelector(querystring); 3785 } 3786 }, { 3787 key: "findElements", 3788 value: function findElements(querystring) { 3789 return this.element.querySelectorAll(querystring); 3790 } 3791 }, { 3792 key: "formatPrice", 3793 value: function formatPrice(price) { 3794 return this.languageHelper.formatPrice(price); 3795 } 3796 }, { 3797 key: "getContactForm", 3798 value: function getContactForm(template) { 3799 var _this43 = this; 3800 3801 this.options.setOption('form_id', template.contactform_id); 3802 var contactForm = new RecrasContactForm(this.options); 3803 return contactForm.getContactFormFields().then(function () { 3804 _this43.contactForm = contactForm; 3805 return contactForm; 3806 }); 3807 } 3808 }, {
3809 key: "getVoucherTemplates", 3810 value: function getVoucherTemplates() { 3811 var _this44 = this; 3812 3813 return this.fetchJson(this.options.getApiBase() + 'voucher_templates').then(function (templates) { 3814 templates = templates.filter(function (template) { 3815 return !!template.contactform_id; 3816 }); 3817 _this44.templates = templates; 3818 return templates; 3819 }); 3820 } 3821 }, { 3822 key: "maybeAddLatestErrorElement", 3823 value: function maybeAddLatestErrorElement() { 3824 var errorEl = this.findElement('.latestError'); 3825 3826 if (!errorEl) { 3827 this.appendHtml("<div class=\"latestError\"></div>"); 3828 } 3829 } 3830 }, { 3831 key: "maybeDisableBuyButton", 3832 value: function maybeDisableBuyButton() { 3833 var button = this.findElement('.buyTemplate'); 3834 3835 if (!button) { 3836 return false; 3837 } 3838 3839 var shouldDisable = false; 3840 this.contactForm.removeErrors(); 3841 3842 if (this.contactForm.hasEmptyRequiredFields() || !this.contactForm.isValid() || !this.contactForm.checkRequiredCheckboxes()) { 3843 this.contactForm.showErrors(); 3844 shouldDisable = true; 3845 } 3846 3847 if (shouldDisable) { 3848 button.setAttribute('disabled', 'disabled'); 3849 } else { 3850 button.removeAttribute('disabled'); 3851 } 3852 } 3853 }, { 3854 key: "showBuyButton", 3855 value: function showBuyButton() { 3856 var html = "<div><button type=\"submit\" class=\"buyTemplate\" disabled>".concat(this.languageHelper.translate('BUTTON_BUY_NOW'), "</button></div>"); 3857 this.appendHtml(html); 3858 this.findElement('.buyTemplate').addEventListener('click', this.buyTemplate.bind(this)); 3859 } 3860 }, { 3861 key: "showContactForm", 3862 value: function showContactForm(template) { 3863 var _this45 = this; 3864 3865 return this.getContactForm(template).then(function (form) { 3866 return form.generateForm({ 3867 voucherQuantitySelector: true, 3868 quantityTerm: _this45.selectedTemplate.quantity_term 3869 }); 3870 }).then(function (html) { 3871 _this45.appendHtml(html); 3872 3873 _this45.showBuyButton(); 3874 3875 _toConsumableArray(_this45.findElements('#number-of-vouchers, [name^="contactformulier"]')).forEach(function (el) { 3876 el.addEventListener('change', _this45.maybeDisableBuyButton.bind(_this45)); 3877 }); 3878 }); 3879 } 3880 }, { 3881 key: "showTemplates", 3882 value: function showTemplates(templates) { 3883 var _this46 = this; 3884 3885 var templateOptions = templates.map(function (template) { 3886 return "<option value=\"".concat(template.id, "\">").concat(template.name, " (").concat(_this46.formatPrice(template.price), ")"); 3887 }); 3888 var html = "<select class=\"recrasVoucherTemplates\"><option>".concat(templateOptions.join(''), "</select>"); 3889 this.appendHtml("<div class=\"recras-voucher-templates\">".concat(html, "</div>")); 3890 var voucherSelectEl = this.findElement('.recrasVoucherTemplates'); 3891 voucherSelectEl.addEventListener('change', function () { 3892 var selectedTemplateId = parseInt(voucherSelectEl.value, 10); 3893 3894 _this46.changeTemplate(selectedTemplateId); 3895 }); 3896 } 3897 }, { 3898 key: "totalPrice", 3899 value: function totalPrice() { 3900 return this.selectedTemplate.price * this.findElement('#number-of-vouchers').value; 3901 } 3902 }]); 3903 3904 return RecrasVoucher; 3905}();
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.