1jQuery(window).on('load', function () { 2 3 let searchParams = new URLSearchParams(window.location.search) 4 if (!(searchParams.has('invoker') && searchParams.get('invoker') === 'phbookingsearch')) { 5 return; 6 } 7 8 const isSummaryPage = jQuery('#ph_search_product_view').val() === 'summary' ? true : false; 9 10 const data = { 11 action: 'ph_get_search_params' 12 } 13 14 let productId = jQuery('form.cart #phive_product_id').val(); 15 var producData= ''; 16 jQuery.post(ph_booking_autofill.ajaxurl, data, function (response) { 17 18 const { search_params } = response?.data || {}; 19 20 if (!search_params) { 21 return; 22 } 23 24 let participants = search_params['ph_book_search_participants']; 25 let totalParticipants = 0; 26 participants = participants.replace(/\\/g, ""); 27 participants = JSON.parse(participants); 28 let productParticipant = []; 29 // Iterate through each participant section 30 jQuery('.participant_inner_section').each(function (index) { 31 // Find the input field within the current participant section 32 33 var inputField = jQuery(this).find('input.input-person'); 34 35 var participantType = inputField.data('name'); 36
37 participants.forEach(participant => { 38 39 // Autofill the input field with the corresponding value 40 if (participant.rule == participantType) { 41 inputField.val(participant.count); 42 } 43 44 }); 45 }); 46 47 //Setting the product page from date in search bar 48 var fromDate = search_params['book_search_from']; 49 jQuery('#ph_book_search_from').val(fromDate); 50 51 //Setting the product page to date in search bar 52 var toDate = search_params['book_search_to']; 53 jQuery('#ph_book_search_to').val(toDate); 54 //Setting the product page participant count for each rule 55 var participantNameCount = ''; 56 var hiddenInputsPersons = ''; 57 var hiddenInputsRules = ''; 58 var hiddenInputsbooking = ''; 59 60 61 jQuery('#ph_book_search_number_of_participants_button .ph_participant-group').each(function () { 62 63 let participantRule = jQuery(this).data('participant'); 64 let inputField = jQuery(this).find('input[type="number"]'); 65 66 participants.forEach(participant => { 67 if (participant.rule === participantRule) { 68 inputField.val(participant.count); 69 totalParticipants += participant.count; 70 if(participant.count > 0) { 71 participantNameCount += `${participant.rule} ${participant.count}, `; 72 } 73 productParticipant.push(participant.count); 74 75 hiddenInputsPersons += `<input type="hidden" name="phive_book_persons[]" class="phive_book_persons" value="${participant.count}">`; 76 hiddenInputsRules += `<input type="hidden" name="ph_person_rule[]" class="ph_person_rule" value="${participant.rule}">`; 77 hiddenInputsbooking = `<input type="hidden" name="persons_as_booking" class="persons_as_booking" value="no">`; 78 } 79 }); 80 }); 81 82 jQuery('form.cart').append(hiddenInputsPersons); 83 jQuery('form.cart').append(hiddenInputsRules); 84 jQuery('form.cart').append(hiddenInputsbooking); 85 86 hiddenInputsPersons = ''; 87 hiddenInputsRules = ''; 88 hiddenInputsbooking = ''; 89 participantNameCount = participantNameCount.trim().replace(/,$/, ''); 90 91 //Setting the product page total participant count in search bar 92 jQuery('#participant_count_display').text(totalParticipants); 93 94 //Setting the product page asset item in search bar 95 let assetId = search_params['ph_search_asset_name']; 96 let assetItem = jQuery('.ph_book_search_asset_item[data-value="' + assetId + '"]'); //#ph_book_search_asset_list 97 var assetName = ''; 98 if (assetItem.length > 0) { 99 assetName = assetItem.attr('title'); 100 jQuery('#ph_asset_name').val(assetName); 101 jQuery('#ph_asset_name').attr('data-ph-search-asset-id', assetId); 102 } 103 104 //product summary deatils 105 jQuery(document).ready(function () { 106 setTimeout(function () { 107 if (search_params.book_search_from) { 108 jQuery('#ph_product_from_date').text(search_params.book_search_from); 109 jQuery('label[for="ph_product_from_date_label"]').text(search_params.ph_from_date_text ? search_params.ph_from_date_text + ':' : '').toggle(!!search_params.ph_from_date_text); 110 } else { 111 jQuery('#ph_product_from_date').closest('.ph_product_row').hide(); 112 } 113 114 if (search_params.book_search_to) { 115 jQuery('#ph_product_to_date').text(search_params.book_search_to); 116 jQuery('label[for="ph_product_to_date_label"]').text(search_params.ph_to_date_text ? search_params.ph_to_date_text + ':' : '').toggle(!!search_params.ph_to_date_text); 117 } else { 118 jQuery('#ph_product_to_date').closest('.ph_product_row').hide(); 119 } 120 121 if (assetName) { 122 jQuery('#ph_product_asset_name').text(assetName); 123 jQuery('label[for="ph_product_asset_name_label"]').text(search_params.ph_asset_label ? search_params.ph_asset_label + ':' : '').toggle(!!search_params.ph_asset_label); 124 } else { 125 jQuery('#ph_product_asset_name').closest('.ph_product_row').hide(); 126 } 127 128 if (participantNameCount) { 129 jQuery('#ph_product_participant_name_count').text(participantNameCount); 130 jQuery('label[for="ph_product_participant_label"]').text(search_params.ph_participant_lable ? search_params.ph_participant_lable + ':' : '').toggle(!!search_params.ph_participant_lable); 131 } else { 132 jQuery('#ph_product_participant_name_count').closest('.ph_product_row').hide(); 133 } 134 jQuery('label[for="ph_booking_cost_label"]').text('Booking Cost:'); 135 jQuery('.ph_outer_container').addClass('loaded'); 136 }, 1000); 137 }); 138 139 if (search_params.ph_product_view) { 140 jQuery('#ph_product_views').val(search_params.ph_product_view); 141 } else { 142 jQuery('#ph_product_views').closest('.ph_product_row').hide(); 143 } 144 145 /** 146 * Updating hidden fields manually to handle add to cart when using summary page. 147 */ 148 149 // Formatting date for month calendar.
150 if ('month' === jQuery('.book_interval_period').val()) { 151 152 let dateStr = search_params.book_search_from; 153 let yearAndMonth = moment(dateStr).format("YYYY-MM"); // Format to get "YYYY-MM" 154 155 jQuery('.ph-date-from').val(yearAndMonth || ''); 156 jQuery('.ph-date-to').val(yearAndMonth || ''); 157 } 158 else { 159 160 jQuery('.ph-date-from').val(search_params.book_search_from || ''); 161 162 const dateTo = getDatePart(search_params.book_search_to) + ' ' + getTimePart(new Date(search_params.book_search_to), 'to'); 163 164 // jQuery('.ph-date-to').val(search_params.book_search_to || ''); 165 jQuery('.ph-date-to').val(dateTo); 166 } 167 168 jQuery('.display_time_from').val(search_params.book_search_from); 169 jQuery('.display_time_to').val(search_params.book_search_to); 170 171 jQuery('.phive_book_assets').val(assetName || ''); 172 173 // Autofill Asset. 174 // When asset is empty considering first available asset. 175 if (!search_params['ph_search_asset_name'] || jQuery('.phive_book_assets option[value="' + search_params['ph_search_asset_name'] + '"]').length == 0 ) { 176 jQuery('.phive_book_assets').prop('selectedIndex', 0); 177 } else { 178 jQuery('.phive_book_assets option[value="' + search_params['ph_search_asset_name'] + '"]').prop('selected', 'true'); 179 } 180 181 // Checks whether all dayes of the month aren't bookable. 182 const totalDays = jQuery('.ph-calendar-days li').length; 183 const unavailableDays = jQuery('.ph-calendar-days li.de-active').length; 184
185 // Triggering month change to next month. 186 if (totalDays == unavailableDays) { 187 jQuery('.ph-next').trigger('click'); 188 } 189 190 setTimeout(() => { 191 checkAndSelect(search_params); 192 }, 500); 193 194 jQuery(document).on('change', '.ph-ul-time', function () { 195 196 jQuery(".ph-ul-time li").each(function () { 197 const date = jQuery(this).find(".callender-full-date").val(); 198 199 const time = date.split(' ')[1]; 200 201 if (jQuery('.selected-date').length == 0) { 202 if (time == search_params['ph_book_search_range_from'] && !jQuery(this).hasClass('de-active') && !jQuery(this).hasClass('not-available') && !jQuery(this).hasClass('booking-full') && !jQuery(this).hasClass('non-working-time')) { 203 jQuery(this).trigger('click'); 204 } 205 } 206 }); 207 }); 208 209 // Cost calculation to be triggered manually only for summary page. 210 if (isSummaryPage) { 211 212 var addon_data = jQuery('.addon').serialize(); 213 if (parseInt(jQuery(".wc-pao-addon-field").length) > 0) { 214 addon_data = jQuery('.wc-pao-addon-field').serialize(); 215 } 216 217 // Handling extra slot at the end for summary page cost calculation. 218 const intervalPeriod = jQuery('.book_interval_period').val(); 219 220 if (search_params['ph_book_search_filter_date_and_time'] && ['hour', 'minute'].includes(intervalPeriod)) { 221 const dateTime = new Date(toDate); 222 toDate = getDatePart(toDate) + ' ' + getTimePart(dateTime, 'to'); 223 } 224 225 var producData = { 226 action: 'phive_get_booked_price', 227 // security : phive_booking_ajax.security, 228 product_id: productId, 229 book_from: fromDate, 230 book_to: toDate, 231 person_details: productParticipant, 232 asset: assetId, 233 addon_data: addon_data, 234 autofill: 'autofill-summary' 235 }; 236 237 var result = ''; 238 jQuery.post(ph_booking_autofill.ajaxurl, producData, function (res) { 239 result = jQuery.parseJSON(res); 240 setTimeout(() => { 241 jQuery('#ph_booking_cost').html(result.price_html); 242 }, 1000); 243 }); 244 } 245 246 }); 247 248 function checkAndSelect(search_params) { 249 250 let isDateFound = false; 251 252 // For date part, we have to match pattern according to widget settings. 253 let searchFromDateTime = search_params['book_search_from']; 254 let searchToDateTime = search_params['book_search_to']; 255 256 const fromDate = getDatePart(searchFromDateTime); 257 const toDate = getDatePart(searchToDateTime); 258 259 searchFromDateTime = new Date(search_params['book_search_from']); 260 searchToDateTime = new Date(search_params['book_search_to']); 261 262 const fromTime = getTimePart(searchFromDateTime); 263 const toTime = getTimePart(searchToDateTime, 'to'); 264 const across_day = jQuery('.across_the_day_booking').val(); 265 const interval_period = jQuery('.book_interval_period').val(); 266 267 // When searched for Range calendar. 268 if (!search_params['ph_fixed_date']) { 269 270 // For month calendar 271 if ('month' == interval_period) { 272 273 const monthFromDate = new Date(fromDate); 274 const monthFromYear = monthFromDate.getFullYear(); 275 const monthFrom = (monthFromDate.getMonth() + 1).toString().padStart(2, '0'); 276 277 // Combine year and month 278 const fromYearMonth = `${monthFromYear}-${monthFrom}`; 279 280 const monthToDate = new Date(toDate); 281 const monthToYear = monthToDate.getFullYear(); 282 const monthTo = (monthToDate.getMonth() + 1).toString().padStart(2, '0'); 283 284 // Combine year and month 285 const toYearMonth = `${monthToYear}-${monthTo}`; 286 287 jQuery(".ph-calendar-days li").each(function () { 288 const date = jQuery(this).find(".callender-full-date").val(); 289 290 if (fromYearMonth == date && !jQuery(this).hasClass('de-active')) { 291 jQuery(this).trigger('click'); 292 293 jQuery(".ph-calendar-days li").each(function () { 294 const date = jQuery(this).find(".callender-full-date").val(); 295 296 if (fromYearMonth != toYearMonth && toYearMonth == date && !jQuery(this).hasClass('de-active')) { 297 setTimeout(() => { 298 jQuery(this).trigger('click'); 299 }, 1000); 300 } 301 }); 302 } 303 }); 304 } 305 306 jQuery(".ph-calendar-days li").each(function () { 307 308 const date = jQuery(this).find(".callender-full-date").val(); 309 if ( 310 date == fromDate 311 && !jQuery(this).hasClass('temporary-unavailable') 312 && !jQuery(this).hasClass('ph-next-month-date') 313 ) { 314 isDateFound = true; 315 jQuery(this).trigger('click'); 316 317 // When across day booking is enabled and searched for time calendar. 318 if ('yes' == across_day && search_params['ph_book_search_filter_date_and_time']) { 319 320 // Select the from time. 321 if (fromTime) { 322 selectFromTime(fromDate, fromTime); 323 } 324 325 // Calculate the range difference and trigger next day click. 326 const count = calculateRangeDifference(fromDate, toDate); 327 328 function triggerClickWithDelay(index) { 329 330 // Trigger next day click until the range is met. 331 if (index < count) { 332 setTimeout(function() { 333 // Trigger the click 334 jQuery('.ph-next-day-time').trigger('click'); 335 336 // Call the next iteration 337 triggerClickWithDelay(index + 1); 338 }, 1000); 339 } else { 340 // Else condition triggers when all the across day clicks are done, so now we can trigger time selection. 341 if (toTime) { 342 selectToTime(toDate, toTime, count); 343 } 344 } 345 } 346 347 // Start the loop from index 0 348 setTimeout(() => { 349 triggerClickWithDelay(0); 350 }, 1000); 351 } 352 } 353 354 if (date == toDate && (!fromTime || !search_params['ph_book_search_filter_date_and_time'])) { 355 setTimeout(() => { 356 jQuery(this).trigger('click'); 357 }, 1000); 358 } 359 }); 360 } 361 // When searched for Fixed calendar 362 else { 363 364 // For month calendar
365 if ('month' == interval_period) { 366 367 const date = new Date(fromDate); 368 const year = date.getFullYear(); 369 const month = (date.getMonth() + 1).toString().padStart(2, '0'); 370 371 // Combine year and month 372 const yearMonth = `${year}-${month}`; 373 374 jQuery(".ph-calendar-days li").each(function () { 375 const date = jQuery(this).find(".callender-full-date").val(); 376 377 if (yearMonth == date && !jQuery(this).hasClass('de-active')) { 378 jQuery(this).trigger('click'); 379 } 380 }); 381 } else { 382 383 // For calendars other than month. 384 jQuery(".ph-calendar-days li").each(function () { 385 const date = jQuery(this).find(".callender-full-date").val(); 386 387 if ( 388 date == fromDate 389 && !jQuery(this).hasClass('temporary-unavailable') 390 && !jQuery(this).hasClass('ph-next-month-date') 391 ) { 392 isDateFound = true; 393 jQuery(this).trigger('click'); 394 } 395 }); 396 } 397 } 398 399 // When from date isn't bookable, move to next month and do the search. 400 if (!isDateFound && 'month' != interval_period) { 401 jQuery('.ph-next').trigger('click'); 402 setTimeout(() => { 403 checkAndSelect(search_params); 404 }, 500); 405 } 406 407 if (across_day == 'no' || search_params['ph_fixed_date']) { 408 409 // From time selection. 410 if (fromTime) { 411 selectFromTime(fromDate, fromTime); 412 } 413 414 // To time selection. 415 if (toTime) { 416 selectToTime(toDate, toTime); 417 } 418 } 419 } 420 421 /** 422 * Get time part from given dateTime. 423 */ 424 function getTimePart(dateTime, type = '') { 425 426 // Handling extra slot at the end. 427 if ('to' == type) { 428 const interval = jQuery('.book_interval').val(); 429 const intervalPeriod = jQuery('.book_interval_period').val(); 430 const isFixedDateSearch = jQuery('#ph_fixed_date').val(); 431 432 // Extra slots get added only for range search. 433 if ('minute' === intervalPeriod && !isFixedDateSearch) { 434 dateTime.setMinutes(dateTime.getMinutes() - interval); 435 } 436 437 if ('hour' === intervalPeriod && !isFixedDateSearch) { 438 dateTime.setHours(dateTime.getHours() - interval); 439 } 440 } 441 442 // Extract the hours and minutes 443 let hours = dateTime.getHours().toString().padStart(2, "0"); 444 let minutes = dateTime.getMinutes().toString().padStart(2, "0"); 445 446 // Format the time in "HH:MM" format 447 let fromTime = (hours === 0 && minutes === "00") ? null : `${hours}:${minutes}`; 448 449 return fromTime; 450 } 451 452 /** 453 * Get date part from given dateTime. 454 */ 455 function getDatePart(inputDate) { 456 457 const patterns = [ 458 { 459 pattern: /^(?<day>\d{2})-(?<month>\d{2})-(?<year>\d{4})(?: (?<hours>\d{2}):(?<minutes>\d{2}) (?<period>AM|PM))?$/, 460 format: 'dd-mm-yy' 461 }, 462 { 463 pattern: /^(?<day>\d{2})\/(?<month>\d{2})\/(?<year>\d{4})(?: (?<hours>\d{2}):(?<minutes>\d{2}) (?<period>AM|PM))?$/, 464 format: 'dd/mm/yy' 465 }, 466 { 467 pattern: /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})(?: (?<hours>\d{2}):(?<minutes>\d{2}) (?<period>AM|PM))?$/, 468 format: 'yy-mm-dd' 469 }, 470 { 471 pattern: /^(?<year>\d{4})\/(?<month>\d{2})\/(?<day>\d{2})(?: (?<hours>\d{2}):(?<minutes>\d{2}) (?<period>AM|PM))?$/, 472 format: 'yy/mm/dd' 473 } 474 ]; 475 476 477 for (const { pattern } of patterns) { 478 const match = inputDate.match(pattern); 479 if (match) { 480 const { groups } = match; 481 const year = groups.year;
482 const month = groups.month; 483 const day = groups.day; 484 const hours = groups.hours; 485 const minutes = groups.minutes; 486 const time = hours && minutes ? ` ${hours}:${minutes}` : ''; 487 488 return `${year}-${month}-${day}`; 489 } 490 } 491 492 return null; 493 } 494 495 /** 496 * Get date range difference. 497 */ 498 function calculateRangeDifference(fromDate, toDate) { 499 500 let dateFrom = new Date(fromDate); 501 let dateTo = new Date(toDate); 502 503 // Calculate the difference in time. 504 let timeDifference = dateTo - dateFrom; 505 506 // Convert time difference to days 507 let dayDifference = timeDifference / (1000 * 60 * 60 * 24); 508 509 return dayDifference; 510 } 511 512 /** 513 * Select from time. 514 */ 515 function selectFromTime(fromDate, fromTime) { 516 517 // Flag to ensure that click is triggered once. 518 var isFromClicked = false; 519 520 jQuery(document).on('change', '.ph-ul-time', function () { 521 522 jQuery(".ph-ul-time li").each(function () { 523 const date = jQuery(this).find(".callender-full-date").val(); 524 const nextDate = jQuery(this).next().find(".callender-full-date").val(); 525 526 const frmdate = date.split(' ')[0].trim(); 527 const time = date.split(' ')[1].trim(); 528 529 const nextTimeSlot = nextDate ? nextDate.split(' ')[1] : ''; 530 531 if (jQuery('.selected-date').length == 0) { 532 if (fromDate == frmdate && time == fromTime && !jQuery(this).hasClass('de-active') && !jQuery(this).hasClass('not-available') && !jQuery(this).hasClass('booking-full') && !jQuery(this).hasClass('non-working-time')) { 533 isFromClicked = true; 534 jQuery(this).trigger('click'); 535 } else if ( fromTime >= time && fromTime < nextTimeSlot && !isFromClicked) { // When exact slot isn't available 536 jQuery(this).trigger('click'); 537 } 538 } 539 }); 540 }); 541 } 542 543 544 /** 545 * Select to time based on same day or range of days. 546 */ 547 function selectToTime(toDate, toTime, count) { 548 549 // When count is zero, it means selection is for same day, hence for same day ph-ul-time trigger won't happen 550 if (count === 0) { 551 toTimeSelection(toTime); 552 } else { 553 jQuery(document).on('change', '.ph-ul-time', function () { 554 toTimeSelection(toTime) 555 }); 556 } 557 } 558 559 /** 560 * Select to time. 561 */ 562 function toTimeSelection(toTime) { 563 564 // Flag to ensure that click is triggered once. 565 var isToClicked = false; 566 567 jQuery(".ph-ul-time li").each(function () { 568 569 const date = jQuery(this).find(".callender-full-date").val(); 570 const nextDate = jQuery(this).next().find(".callender-full-date").val(); 571 572 const nextTimeSlot = nextDate ? nextDate.split(' ')[1] : ''; 573 574 const time = date.split(' ')[1].trim(); 575 576 if (time == toTime && !jQuery(this).hasClass('de-active') && !jQuery(this).hasClass('not-available') && !jQuery(this).hasClass('booking-full') && !jQuery(this).hasClass('non-working-time')) { 577 isToClicked = true; 578 setTimeout(() => { 579 jQuery(this).trigger('click'); 580 }, 1000); 581 } else if (toTime >= time && toTime < nextTimeSlot && !isToClicked) { // When exact slot isn't available 582 jQuery(this).trigger('click'); 583 } 584 }); 585 } 586});
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.