event-tickets-with-ticket-scanner
Last commit date
3rd
1 week ago
css
1 week ago
img
1 week ago
includes
1 week ago
js
1 week ago
languages
1 week ago
ticket
1 week ago
vendors
1 week ago
SASO_EVENTTICKETS.php
1 week ago
backend.js
1 week ago
changelog-features.json
1 week ago
changelog.txt
1 week ago
db.php
1 week ago
index.php
1 week ago
init_file.php
1 week ago
order_details.js
1 week ago
pwa-sw.js
1 week ago
readme.txt
1 week ago
saso-eventtickets-validator.js
1 week ago
sasoEventtickets_AdminSettings.php
1 week ago
sasoEventtickets_Authtoken.php
1 week ago
sasoEventtickets_Base.php
1 week ago
sasoEventtickets_Core.php
1 week ago
sasoEventtickets_Frontend.php
1 week ago
sasoEventtickets_Messenger.php
1 week ago
sasoEventtickets_Options.php
1 week ago
sasoEventtickets_PDF.php
1 week ago
sasoEventtickets_Seating.php
1 week ago
sasoEventtickets_Ticket.php
1 week ago
sasoEventtickets_TicketBadge.php
1 week ago
sasoEventtickets_TicketDesigner.php
1 week ago
sasoEventtickets_TicketQR.php
1 week ago
ticket_events.js
1 week ago
ticket_scanner.js
1 week ago
validator.js
1 week ago
version-notices.json
1 week ago
vollstart-cross-promo.php
1 week ago
wc_backend.js
1 week ago
wc_frontend.js
1 week ago
woocommerce-hooks.php
1 week ago
wc_frontend.js
533 lines
| 1 | function SasoEventticketsValidator_WC_frontend($, phpObject) { |
| 2 | const { __, _x, _n, sprintf } = wp.i18n; |
| 3 | let _self = this; |
| 4 | let inputTypes = [phpObject.inputType, "text", "value"]; |
| 5 | |
| 6 | function init() { |
| 7 | _addHandlerToTheCodeFields(); |
| 8 | _addHandlerToAddToCartButtons(); // for shop and product pages |
| 9 | } |
| 10 | |
| 11 | function addStyleCode(content) { |
| 12 | let c = document.createElement('style'); |
| 13 | c.innerHTML = content; |
| 14 | document.getElementsByTagName("head")[0].appendChild(c); |
| 15 | } |
| 16 | |
| 17 | function getPidFromAddToCartButton(btn){ |
| 18 | return btn.data('product_id') || btn.attr('data-product_id') || btn.val() || null; |
| 19 | } |
| 20 | |
| 21 | function _addHandlerToAddToCartButtons() { |
| 22 | if (!phpObject.fieldKey) return; |
| 23 | if (!phpObject.has_daychooser) return; // only if at least one product has a date picker |
| 24 | |
| 25 | function findDateForPid(pid, $btn){ |
| 26 | let input_id = phpObject.fieldKey+'_'+pid; |
| 27 | |
| 28 | return $(document.body) |
| 29 | .find('input[data-input-type="daychooser"][data-plugin="event"][data-is-shop-page="1"][data-cart-item-id="'+input_id+'"]') |
| 30 | .first(); |
| 31 | } |
| 32 | |
| 33 | function checkDate(btn, e) { |
| 34 | var pid = getPidFromAddToCartButton(btn); |
| 35 | if (!pid) return true; // manche Themes weichen ab; dann greift serverseitige Prüfung |
| 36 | |
| 37 | var input = findDateForPid(pid, btn); |
| 38 | if (!input || !input.length) return true; // kein Feld gefunden, dann greift serverseitige Prüfung |
| 39 | |
| 40 | var val = (input && input.val ? (input.val()||'').trim() : ''); |
| 41 | |
| 42 | if (!val) { |
| 43 | if (e) { |
| 44 | e.preventDefault(); |
| 45 | e.stopPropagation(); |
| 46 | e.stopImmediatePropagation(); |
| 47 | } |
| 48 | // Kurzes Feedback (ersetze gern durch eigenes Notice-System) |
| 49 | alert(phpObject.daychooser_warning ? phpObject.daychooser_warning : __('Please choose a valid date.', 'event-tickets-with-ticket-scanner')); |
| 50 | return false; |
| 51 | } |
| 52 | return true; |
| 53 | } |
| 54 | |
| 55 | // product page |
| 56 | $(document).on('click', '.single_add_to_cart_button', function(e){ |
| 57 | var btn = $(this); |
| 58 | |
| 59 | if (!checkDate(btn, e)) { |
| 60 | return false; |
| 61 | } |
| 62 | }); |
| 63 | |
| 64 | // product page with AJAX add to cart |
| 65 | var form = document.querySelector('form.cart'); |
| 66 | if (form) { |
| 67 | form.addEventListener('submit', function(e){ |
| 68 | var btn = $(form).find('.single_add_to_cart_button').first(); |
| 69 | if (!btn || btn.length == 0) return; // no button found, then server side check |
| 70 | if (!checkDate(btn, e)) { |
| 71 | return false; |
| 72 | } |
| 73 | var pid = getPidFromAddToCartButton(btn); |
| 74 | if (!pid) return; // manche Themes weichen ab; dann greift serverseitige Prüfung |
| 75 | var $input = findDateForPid(pid, btn); |
| 76 | if ($input && $input.length > 0) { |
| 77 | var val = ($input && $input.val ? ($input.val()||'').trim() : ''); |
| 78 | if (val == "") return false; |
| 79 | // add hidden input field to the form if not already present |
| 80 | var hiddenInput = form.querySelector('input[name="'+phpObject.fieldKey+'"]'); |
| 81 | if (!hiddenInput) { |
| 82 | hiddenInput = document.createElement('input'); |
| 83 | hiddenInput.type = 'hidden'; |
| 84 | hiddenInput.name = phpObject.fieldKey; |
| 85 | form.appendChild(hiddenInput); |
| 86 | } |
| 87 | hiddenInput.value = val ? val : ''; |
| 88 | // indicate that a day chooser was used |
| 89 | var hiddenInputIndicator = form.querySelector('input[name="'+phpObject.fieldDayChooserIndicator+'"]'); |
| 90 | if (!hiddenInputIndicator) { |
| 91 | hiddenInputIndicator = document.createElement('input'); |
| 92 | hiddenInputIndicator.type = 'hidden'; |
| 93 | hiddenInputIndicator.name = phpObject.fieldDayChooserIndicator; |
| 94 | form.appendChild(hiddenInputIndicator); |
| 95 | } |
| 96 | hiddenInputIndicator.value = 1; |
| 97 | } |
| 98 | }); |
| 99 | } |
| 100 | |
| 101 | // shop/archive page: intercept ANY add-to-cart link with data-product_id |
| 102 | // Works with both WC Classic (ajax_add_to_cart) and WC Blocks (plain <a> link) |
| 103 | $(document.body).on('click', 'a[data-product_id]', function(e){ |
| 104 | var btn = $(this); |
| 105 | var pid = getPidFromAddToCartButton(btn); |
| 106 | if (!pid) return; |
| 107 | |
| 108 | var $input = findDateForPid(pid, btn); |
| 109 | if (!$input || !$input.length) return; // not a daychooser product — let WC handle normally |
| 110 | |
| 111 | var val = ($input.val() || '').trim(); |
| 112 | if (!val) { |
| 113 | e.preventDefault(); |
| 114 | e.stopImmediatePropagation(); |
| 115 | alert(phpObject.daychooser_warning ? phpObject.daychooser_warning : __('Please choose a valid date.', 'event-tickets-with-ticket-scanner')); |
| 116 | return false; |
| 117 | } |
| 118 | |
| 119 | // For AJAX buttons (classic WC): let the adding_to_cart handler below add data |
| 120 | if (btn.hasClass('ajax_add_to_cart')) return; |
| 121 | |
| 122 | // For non-AJAX buttons (WC Blocks / plain links): append date to URL |
| 123 | e.preventDefault(); |
| 124 | e.stopImmediatePropagation(); |
| 125 | var url = btn.attr('href'); |
| 126 | if (!url) return; |
| 127 | url += (url.indexOf('?') > -1 ? '&' : '?'); |
| 128 | url += encodeURIComponent(phpObject.fieldKey) + '=' + encodeURIComponent(val); |
| 129 | url += '&' + encodeURIComponent(phpObject.fieldDayChooserIndicator) + '=1'; |
| 130 | var nonce = document.querySelector('input[name="'+phpObject.nonceKey+'"]'); |
| 131 | if (nonce) url += '&' + encodeURIComponent(phpObject.nonceKey) + '=' + encodeURIComponent(nonce.value); |
| 132 | window.location.href = url; |
| 133 | }); |
| 134 | |
| 135 | // shop page with AJAX add to cart (classic WC) |
| 136 | $(document.body).on('adding_to_cart', function(e, $button, data){ |
| 137 | var pid = getPidFromAddToCartButton($button); |
| 138 | if (!pid) return; |
| 139 | |
| 140 | var $input = findDateForPid(pid, $button); |
| 141 | if ($input && $input.length > 0) { |
| 142 | var val = ($input && $input.val ? ($input.val()||'').trim() : ''); |
| 143 | if (val == "") return false; |
| 144 | data[phpObject.fieldKey] = val ? val : ''; |
| 145 | data[phpObject.fieldDayChooserIndicator] = 1; |
| 146 | } |
| 147 | |
| 148 | var nonce = document.querySelector('input[name="'+phpObject.nonceKey+'"]'); |
| 149 | data[phpObject.nonceKey] = nonce ? nonce.value : ''; |
| 150 | }); |
| 151 | |
| 152 | } |
| 153 | |
| 154 | function _addHandlerToTheCodeFields() { |
| 155 | let isStoring = false; |
| 156 | let waitingTimeout = null; |
| 157 | let isChanged = false; |
| 158 | |
| 159 | function sendCode(elem, code, type) { |
| 160 | //clearWaitingTimeout(); |
| 161 | if (!isStoring) { |
| 162 | $('div[class="woocommerce"]').block({ |
| 163 | //message: '...loading...', |
| 164 | message: null, |
| 165 | overlayCSS: { |
| 166 | background: '#fff', |
| 167 | opacity: 0.6 |
| 168 | } |
| 169 | }); |
| 170 | isStoring = true; |
| 171 | let cart_item_id = elem.attr('data-cart-item-id'); |
| 172 | let cart_item_count = elem.attr('data-cart-item-count'); |
| 173 | let nonce = phpObject.nonce; |
| 174 | $.ajax( |
| 175 | { |
| 176 | type: 'POST', |
| 177 | url: phpObject.ajaxurl, |
| 178 | data: { |
| 179 | action: phpObject.action, |
| 180 | a: 'updateSerialCodeToCartItem', |
| 181 | security: nonce, |
| 182 | cart_item_id: cart_item_id, |
| 183 | cart_item_count: cart_item_count, |
| 184 | type: type, |
| 185 | code: code |
| 186 | }, |
| 187 | success: function( response ) { |
| 188 | $('div[class="woocommerce"]').unblock(); |
| 189 | $('.cart_totals').unblock(); |
| 190 | if (response.success) { |
| 191 | elem.val(response.code); |
| 192 | } else { |
| 193 | if (response.msg) alert(response.msg); |
| 194 | } |
| 195 | isStoring = false; |
| 196 | //window.location.reload(); |
| 197 | } |
| 198 | } |
| 199 | ) |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | function clearWaitingTimeout() { |
| 204 | clearTimeout(waitingTimeout); |
| 205 | } |
| 206 | function setWaitingTimeout(elem, code) { |
| 207 | clearWaitingTimeout(); |
| 208 | waitingTimeout = setTimeout(()=>{ |
| 209 | if (isChanged) { |
| 210 | isChanged = false; |
| 211 | sendCode(elem, code); |
| 212 | } |
| 213 | }, 2500); |
| 214 | } |
| 215 | |
| 216 | // finde die code text inputs |
| 217 | // eventcoderrestriction is no longer used, but still in the code |
| 218 | $('body').find('input[data-input-type="eventcoderestriction"][data-plugin="event"]') |
| 219 | .on('keydown',function(e){ |
| 220 | if (e.which === 13) { |
| 221 | e.preventDefault(); |
| 222 | let elem = $(this); |
| 223 | isChanged = true; |
| 224 | sendCode(elem, elem.val().trim(), "saso_eventtickets_request_name_per_ticket"); |
| 225 | } |
| 226 | }) |
| 227 | .on('paste', event=>{ |
| 228 | isStoring = false; |
| 229 | let elem = $(event.srcElement); |
| 230 | let code = (event.clipboardData || window.clipboardData).getData('text'); |
| 231 | if (typeof code == "string") { |
| 232 | code = code.trim(); |
| 233 | isChanged = true; |
| 234 | sendCode(elem, code, "saso_eventtickets_request_name_per_ticket"); |
| 235 | } else { alert("no text"); } |
| 236 | }) |
| 237 | .on('change',function(){ |
| 238 | let elem = $(this); |
| 239 | let code = elem.val().trim(); |
| 240 | //let cart_item_id = elem.data('cart-item-id'); |
| 241 | //let d = document.querySelector('input[data-cart-item-id="'+cart_item_id+'"]').value |
| 242 | isChanged = true; |
| 243 | sendCode(elem, code, "saso_eventtickets_request_name_per_ticket"); |
| 244 | }) |
| 245 | /* |
| 246 | .on('blur',function(){ |
| 247 | let elem = $(this); |
| 248 | let code = elem.val().trim(); |
| 249 | if (code != "" && isChanged) { |
| 250 | let cart_item_id = elem.data('cart-item-id'); |
| 251 | //let d = document.querySelector('input[data-cart-item-id="'+cart_item_id+'"]').value |
| 252 | sendCode(elem, code, "saso_eventtickets_request_name_per_ticket"); |
| 253 | } |
| 254 | }) |
| 255 | */ |
| 256 | .removeAttr('disabled'); |
| 257 | |
| 258 | $('body').find('input[data-input-type="text"][data-plugin="event"]') |
| 259 | .on('keydown',function(e){ |
| 260 | if (e.which === 13) { |
| 261 | e.preventDefault(); |
| 262 | let elem = $(this); |
| 263 | isChanged = true; |
| 264 | sendCode(elem, elem.val().trim(), "saso_eventtickets_request_name_per_ticket"); |
| 265 | } |
| 266 | }) |
| 267 | .on('paste', event=>{ |
| 268 | isStoring = false; |
| 269 | let elem = $(event.srcElement); |
| 270 | let code = (event.clipboardData || window.clipboardData).getData('text'); |
| 271 | if (typeof code == "string") { |
| 272 | code = code.trim(); |
| 273 | isChanged = true; |
| 274 | sendCode(elem, code, "saso_eventtickets_request_name_per_ticket"); |
| 275 | } else { alert("no text"); } |
| 276 | }) |
| 277 | .on('change',function(){ |
| 278 | let elem = $(this); |
| 279 | let code = elem.val().trim(); |
| 280 | isChanged = true; |
| 281 | sendCode(elem, code, "saso_eventtickets_request_name_per_ticket"); |
| 282 | }) |
| 283 | .removeAttr('disabled'); |
| 284 | |
| 285 | $('body').find('select[data-input-type="value"][data-plugin="event"]') |
| 286 | .on('change',function(){ |
| 287 | let elem = $(this); |
| 288 | let code = elem.val().trim(); |
| 289 | isChanged = true; |
| 290 | sendCode(elem, code, "saso_eventtickets_request_value_per_ticket"); |
| 291 | }) |
| 292 | .removeAttr('disabled'); |
| 293 | |
| 294 | // Resolve a min/max value (number-of-days, YYYY-MM-DD, or empty) → JS Date or null. |
| 295 | function _sasoResolveLimitDate(opt) { |
| 296 | if (opt == null || opt === '') return null; |
| 297 | if (typeof opt === 'number' && !isNaN(opt)) { |
| 298 | let d = new Date(); d.setHours(0, 0, 0, 0); d.setDate(d.getDate() + opt); |
| 299 | return d; |
| 300 | } |
| 301 | let s = String(opt).trim(); |
| 302 | let m = s.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/); |
| 303 | if (m) return new Date(parseInt(m[1], 10), parseInt(m[2], 10) - 1, parseInt(m[3], 10)); |
| 304 | let n = parseInt(s, 10); |
| 305 | if (!isNaN(n)) { |
| 306 | let d = new Date(); d.setHours(0, 0, 0, 0); d.setDate(d.getDate() + n); |
| 307 | return d; |
| 308 | } |
| 309 | return null; |
| 310 | } |
| 311 | |
| 312 | // Selectability rules — kept in sync with beforeShowDay below intentionally. |
| 313 | function _sasoIsDateSelectable(date, attrs) { |
| 314 | if (attrs.excludeWdays) { |
| 315 | let excludedDays = attrs.excludeWdays.split(','); |
| 316 | if (excludedDays.indexOf(date.getDay().toString()) !== -1) return false; |
| 317 | } |
| 318 | let today = new Date(); today.setHours(0, 0, 0, 0); |
| 319 | let chk = new Date(date.getFullYear(), date.getMonth(), date.getDate()); |
| 320 | if (chk < today) return false; |
| 321 | if (attrs.excludeDates) { |
| 322 | let excludedDates = attrs.excludeDates.split(','); |
| 323 | let m = date.getMonth() + 1; |
| 324 | let d = date.getDate(); |
| 325 | let dateStr = date.getFullYear() + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d; |
| 326 | if (excludedDates.indexOf(dateStr) !== -1) return false; |
| 327 | } |
| 328 | return true; |
| 329 | } |
| 330 | |
| 331 | // Scan up to 24 months forward from `from` for the first selectable day. |
| 332 | // Used as datepicker.defaultDate so the picker opens on the first month |
| 333 | // that actually has free slots — instead of an all-grey current month. |
| 334 | function _sasoFindFirstSelectableDate(attrs, from, until) { |
| 335 | let cap = 24; |
| 336 | let start = from ? new Date(from.getFullYear(), from.getMonth(), from.getDate()) |
| 337 | : (function () { let t = new Date(); t.setHours(0, 0, 0, 0); return t; })(); |
| 338 | let scanFrom = new Date(start); |
| 339 | for (let i = 0; i < cap; i++) { |
| 340 | let monthEnd = new Date(scanFrom.getFullYear(), scanFrom.getMonth() + 1, 0); |
| 341 | let lastDay = (until && monthEnd > until) ? until : monthEnd; |
| 342 | for (let d = new Date(scanFrom); d <= lastDay; d.setDate(d.getDate() + 1)) { |
| 343 | if (_sasoIsDateSelectable(d, attrs)) return new Date(d); |
| 344 | } |
| 345 | scanFrom = new Date(scanFrom.getFullYear(), scanFrom.getMonth() + 1, 1); |
| 346 | if (until && scanFrom > until) return null; |
| 347 | } |
| 348 | return null; |
| 349 | } |
| 350 | |
| 351 | $('body').find('input[data-input-type="daychooser"][data-plugin="event"]') |
| 352 | .on('keydown', function(e) { e.preventDefault(); }) |
| 353 | .on('paste', function(e) { e.preventDefault(); }) |
| 354 | .each((idx, input) => { |
| 355 | let elem_intern = $(input); |
| 356 | let dateFormat = elem_intern.attr('placeholder'); |
| 357 | dateFormat = dateFormat != null ? dateFormat.trim() : ''; |
| 358 | dateFormat = dateFormat ? dateFormat : 'YYYY-MM-DD'; |
| 359 | dateFormat = 'YYYY-MM-DD'; |
| 360 | elem_intern.attr('placeholder', __(dateFormat)); |
| 361 | let data_offset_start = 0; |
| 362 | let data_offset_end = 0; |
| 363 | try { |
| 364 | data_offset_start = parseInt(elem_intern.attr('data-offset-start')); |
| 365 | } catch (error) { |
| 366 | //console.log(error); |
| 367 | } |
| 368 | if (elem_intern.attr('min') && elem_intern.attr('min').length > 0) { |
| 369 | data_offset_start = elem_intern.attr('min'); |
| 370 | } |
| 371 | // Same-day cutoff: runs after min-attribute override so absolute start dates |
| 372 | // (ticket_start_date) cannot silently undo the cutoff effect. |
| 373 | // If current time >= cutoff and the resolved minDate still includes today, shift to tomorrow. |
| 374 | let _saso_cutoff = elem_intern.attr('data-cutoff-time'); |
| 375 | if (_saso_cutoff) { |
| 376 | let _cp = _saso_cutoff.split(':'); |
| 377 | let _cutoffDate = new Date(); |
| 378 | _cutoffDate.setHours(parseInt(_cp[0], 10), parseInt(_cp[1], 10), 0, 0); |
| 379 | if (new Date() >= _cutoffDate) { |
| 380 | let _todayMidnight = new Date(); _todayMidnight.setHours(0, 0, 0, 0); |
| 381 | let _resolvedMin = _sasoResolveLimitDate(data_offset_start); |
| 382 | if (_resolvedMin === null || _resolvedMin <= _todayMidnight) { |
| 383 | data_offset_start = 1; |
| 384 | } |
| 385 | } |
| 386 | } |
| 387 | try { |
| 388 | data_offset_end = parseInt(elem_intern.attr('data-offset-end')); |
| 389 | } catch (error) { |
| 390 | //console.log(error); |
| 391 | } |
| 392 | if (elem_intern.attr('max') && elem_intern.attr('max').length > 0) { |
| 393 | data_offset_end = elem_intern.attr('max'); |
| 394 | } |
| 395 | //let today = new Date(); |
| 396 | //let start = new Date(today.getFullYear(), today.getMonth(), today.getDate() + data_offset_start); |
| 397 | //let end = new Date(today.getFullYear(), today.getMonth(), today.getDate() + data_offset_end); |
| 398 | |
| 399 | let _saso_attrs = { |
| 400 | excludeWdays: elem_intern.attr('data-exclude-wdays') || '', |
| 401 | excludeDates: elem_intern.attr('data-exclude-dates') || '' |
| 402 | }; |
| 403 | let _saso_minAbs = _sasoResolveLimitDate(data_offset_start); |
| 404 | let _saso_maxAbs = _sasoResolveLimitDate(data_offset_end); |
| 405 | let _saso_default = _sasoFindFirstSelectableDate(_saso_attrs, _saso_minAbs, _saso_maxAbs); |
| 406 | |
| 407 | elem_intern.datepicker({ |
| 408 | dateFormat: 'yy-mm-dd', |
| 409 | //dateFormat: dateFormat, |
| 410 | showWeek: true, |
| 411 | firstDay: 1, |
| 412 | hideIfNoPrevNext : true, |
| 413 | minDate: data_offset_start, |
| 414 | maxDate: data_offset_end, |
| 415 | defaultDate: _saso_default, |
| 416 | beforeShow: function(input, options) { |
| 417 | this._sasoevent_input_field = $(input); |
| 418 | }, |
| 419 | beforeShowDay: function(date) { // https://api.jqueryui.com/datepicker/#option-beforeShow |
| 420 | let day = date.getDay(); |
| 421 | let data_exclude_wdays = this._sasoevent_input_field.attr('data-exclude-wdays'); |
| 422 | let selectable = true; |
| 423 | let cssClass = ''; |
| 424 | let toolTipp = ''; |
| 425 | if (data_exclude_wdays && data_exclude_wdays.length > 0) { |
| 426 | let excludedDays = data_exclude_wdays.split(','); |
| 427 | selectable = excludedDays.indexOf(day.toString()) == -1; |
| 428 | |
| 429 | cssClass = selectable ? '' : 'ui-datepicker-unselectable'; |
| 430 | toolTipp = selectable ? '' : __('This day is not selectable'); |
| 431 | } |
| 432 | if (selectable) { |
| 433 | // check if the date is in the past |
| 434 | let today = new Date(); |
| 435 | let y = date.getFullYear(); |
| 436 | let m = date.getMonth() + 1; |
| 437 | let d = date.getDate(); |
| 438 | let dateStr = y + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d; |
| 439 | let todayStr = today.getFullYear() + '-' + (today.getMonth() + 1 < 10 ? '0' : '') + (today.getMonth() + 1) + '-' + (today.getDate() < 10 ? '0' : '') + today.getDate(); |
| 440 | if (dateStr < todayStr) { |
| 441 | selectable = false; |
| 442 | cssClass = 'ui-datepicker-unselectable'; |
| 443 | toolTipp = __('This day is not selectable'); |
| 444 | } |
| 445 | } |
| 446 | if (selectable) { |
| 447 | let data_exclude_dates = this._sasoevent_input_field.attr('data-exclude-dates'); |
| 448 | if (data_exclude_dates && data_exclude_dates.length > 0) { |
| 449 | let excludedDates = data_exclude_dates.split(','); |
| 450 | let y = date.getFullYear(); |
| 451 | let m = date.getMonth() + 1; |
| 452 | let d = date.getDate(); |
| 453 | let dateStr = y + '-' + (m < 10 ? '0' : '') + m + '-' + (d < 10 ? '0' : '') + d; |
| 454 | selectable = excludedDates.indexOf(dateStr) == -1; |
| 455 | |
| 456 | cssClass = selectable ? '' : 'ui-datepicker-unselectable'; |
| 457 | toolTipp = selectable ? '' : __('This day is not selectable'); |
| 458 | } |
| 459 | } |
| 460 | return [selectable, cssClass, toolTipp]; |
| 461 | //return [true, '']; |
| 462 | } |
| 463 | }); |
| 464 | }) |
| 465 | .on('change',event=>{ |
| 466 | let elem_intern = $(event.target); |
| 467 | |
| 468 | if (elem_intern.attr('data-is-shop-page') == "1") return; // only on cart and checkout page |
| 469 | |
| 470 | //console.log('change datepicker', elem_intern.attr('id')); |
| 471 | let date_value = elem_intern.val().trim(); |
| 472 | if (elem_intern.attr('data-previous-value') == date_value) return; // no change |
| 473 | elem_intern.attr('data-previous-value', date_value); |
| 474 | if (date_value) { |
| 475 | sendCode(elem_intern, date_value, "saso_eventtickets_request_daychooser"); |
| 476 | isChanged = true; |
| 477 | let to_be_changed = []; |
| 478 | // update the other date pickers if no value is set to use this date |
| 479 | let data_cart_item_id = elem_intern.attr('data-cart-item-id'); |
| 480 | $('body').find('input[data-input-type="daychooser"][data-plugin="event"][id^="saso_eventtickets_request_daychooser['+data_cart_item_id+']"]').each((idx, input_to_update) => { |
| 481 | //console.log('update datepicker', input_to_update); |
| 482 | let input_elem = $(input_to_update); |
| 483 | let v = input_elem.val().trim(); |
| 484 | if (!v) { |
| 485 | //console.log(input_elem.attr("id")+' set value to: '+date_value); |
| 486 | input_elem.val(date_value); // is not working somehow, so skip this step for now. The value is shown and send to the server, but on the checkout the other fields are empty |
| 487 | to_be_changed.push(input_elem); |
| 488 | } |
| 489 | }); |
| 490 | |
| 491 | // remove the related error message on the cart |
| 492 | //let data_cart_item_count = elem.attr('data-cart-item-count'); |
| 493 | //$('li[data-cart-item-id="'+data_cart_item_id+'"][data-cart-item-count="'+data_cart_item_count+'"]').remove(); |
| 494 | // send data to the server |
| 495 | |
| 496 | let counter = 0; |
| 497 | let wait = 0; |
| 498 | to_be_changed.forEach(input => { |
| 499 | //console.log(input.attr("id")+'send code: '+date_value); |
| 500 | //console.log(input); |
| 501 | window.setTimeout(()=>{ |
| 502 | sendCode(input, date_value, "saso_eventtickets_request_daychooser"); |
| 503 | }, wait); |
| 504 | counter++; |
| 505 | if (wait == 0) wait = 250; |
| 506 | if (counter == to_be_changed.length) { |
| 507 | $(document.body).trigger('update_checkout'); |
| 508 | } |
| 509 | }); |
| 510 | } // end date_value |
| 511 | }) |
| 512 | .each(function() { |
| 513 | // Only remove disabled if not in a locked container (seats selected) |
| 514 | if (!$(this).closest('.saso-datepicker-locked').length) { |
| 515 | $(this).removeAttr('disabled'); |
| 516 | } |
| 517 | }); |
| 518 | |
| 519 | //addStyleCode('#ui-datepicker-div > table {background-color: white;}'); |
| 520 | } |
| 521 | |
| 522 | init(); |
| 523 | |
| 524 | return { |
| 525 | _addHandlerToTheCodeFields: _addHandlerToTheCodeFields, |
| 526 | }; |
| 527 | } |
| 528 | |
| 529 | (function($){ |
| 530 | $(document).ready(function(){ |
| 531 | window.SasoEventticketsValidator_WC_frontend = SasoEventticketsValidator_WC_frontend($, SasoEventticketsValidator_phpObject); |
| 532 | }); |
| 533 | })(jQuery); |