The script below works perfectly in playcode.io (or other), but fails to detect a click when injected into my site. I’m more of a PHP developer and am sure I’ve made some rookie JS mistakes here.
The purpose of the script is to detect a click on a Woocommerce Bookings’ calendar and determine whether the date clicked meets the condition and if so, set the value of a form field and hide the <div>
in which that field resides to prevent manual user selection.
The script is currently being injected through the footer.php file in my child theme. It shows up near the bottom just under the /woocommerce script/ comment.
- Is there a way to use the
<td>
‘s attributes: “data-handler=’selectDay'” and/or the “data-event=’click'” to detect the click through a passive event listener? - Is there a way to do this with pure JS?
- Is there some WordPress thing I’m not doing here for this to work inside WP?
Here is the code I’ve used successfully on playcode:
Javascript
jQuery(document).ready(function(){
//detect a click in a <td> within the woocommerce bookings calendar <table>
jQuery(document).on('click', '.ui-datepicker-calendar td', function() {
//DEBUG ONLY - CONFIRM CLICK IS DETECTED - DELETE WHEN WORKING.
//alert('click detected');
// get the closest TD in the current row
var currentRow = jQuery(this).closest("td");
// get the year from the wc attribute
var rawyear = parseInt(jQuery(this).attr("data-year"));
//get the month from the wc attribute
var rawmonth = parseInt(jQuery(this).attr("data-month"));
//get the day from the text inside the <td>
var rawday = parseInt(currentRow.find(".ui-state-default").html());
//use the month, day and year to set the selected start date.
var startDate = new Date(rawyear, rawmonth, rawday, 0, 0, 0);
//get the current date
var today = new Date();
//set the year for the cutoff date
var compYear = today.getFullYear();
//set the month for the cutoff date
var compMonth = today.getMonth();
//set how many days into the future is the cuttoff (4-days in this case)
var compDay = today.getDate() + 4;
//set full cuttoff date as variable
var cuttoffDate = new Date(compYear, compMonth, compDay, 0, 0, 0);
//compare the date clicked with the cuttoff date. if the start date is less than or equal to the cutoff date...
if(startDate <= cuttoffDate && currentRow[0].className.includes('bookable')) {
//set deposit option form field to "pay-in-full"
pif = document.getElementById("wc-option-pay-full");
pif.checked = true;
//hide the deposit options
document.getElementsByClassName('wc-deposits-wrapper')[0].style.display = 'none';
//output the cutoff date to the console for debugging
console.log('Pay-in-full on or before', cuttoffDate);
} else {
//set deposit option form field to "pay-deposit"
pd = document.getElementById("wc-option-pay-deposit");
pd.checked = true;
//show the deposit options
document.getElementsByClassName('wc-deposits-wrapper')[0].style.display = 'block';
//log deposit allowed for debug
console.log("Deposit allowed");
}
});
});
HTML
<div class="elementor-element elementor-element-87d3bf4 elementor-add-to-cart--align-center form-flat brnm-cart-form elementor-widget elementor-widget-woocommerce-product-add-to-cart" data-id="87d3bf4" data-element_type="widget" id="brnm-single-product-cart" data-widget_type="woocommerce-product-add-to-cart.default">
<div class="elementor-widget-container">
<div class="elementor-add-to-cart elementor-product-booking">
<noscript>Your browser must support JavaScript in order to make a booking.</noscript>
<form class="cart" method="post" enctype="multipart/form-data" data-nonce="3b9e71d474">
<div id="wc-bookings-booking-form" class="wc-bookings-booking-form" style="">
<p class="form-field form-field-wide wc_bookings_field_persons_4097">
<label for="wc_bookings_field_persons_4097">Passengers:</label>
<input type="number" value="1" step="1" min="1" max="6" name="wc_bookings_field_persons_4097" id="wc_bookings_field_persons_4097"> </p>
<fieldset class="wc-bookings-date-picker wc_bookings_field_start_date">
<p class="wc-bookings-date-picker-timezone-block" style="" align="center">
Times are in <span class="wc-bookings-date-picker-timezone">America/Los Angeles</span>
</p>
<div class="picker hasDatepicker" data-display="always_visible" data-default-availability="true" data-min_date="+0d"
data-max_date="+12m" data-default_date="2020-06-07" id="dp1591455711928" style="position: static; zoom: 1;">
<div class="ui-datepicker-inline ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"
style="display: block;">
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all"><a
class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="Previous"><span
class="ui-icon ui-icon-circle-triangle-w">Previous</span></a><a
class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click" title="Next"><span
class="ui-icon ui-icon-circle-triangle-e">Next</span></a>
<div class="ui-datepicker-title"><span class="ui-datepicker-month">June</span> <span
class="ui-datepicker-year">2020</span></div>
</div>
<table class="ui-datepicker-calendar">
<thead>
<tr>
<th scope="col"><span title="Monday">M</span></th>
<th scope="col"><span title="Tuesday">T</span></th>
<th scope="col"><span title="Wednesday">W</span></th>
<th scope="col"><span title="Thursday">T</span></th>
<th scope="col"><span title="Friday">F</span></th>
<th scope="col" class="ui-datepicker-week-end"><span title="Saturday">S</span></th>
<th scope="col" class="ui-datepicker-week-end"><span title="Sunday">S</span></th>
</tr>
</thead>
<tbody>
<tr>
<td class=" ui-datepicker-unselectable ui-state-disabled bookable" title="This date is available">
<span class="ui-state-default">1</span></td>
<td class=" ui-datepicker-unselectable ui-state-disabled bookable" title="This date is available">
<span class="ui-state-default">2</span></td>
<td class=" ui-datepicker-unselectable ui-state-disabled bookable" title="This date is available">
<span class="ui-state-default">3</span></td>
<td class=" ui-datepicker-unselectable ui-state-disabled bookable" title="This date is available">
<span class="ui-state-default">4</span></td>
<td class=" ui-datepicker-unselectable ui-state-disabled bookable" title="This date is available">
<span class="ui-state-default">5</span></td>
<td class=" ui-datepicker-week-end partial_booked bookable ui-datepicker-today"
title="This date is partially booked - but bookings still remain" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a
class="ui-state-default ui-state-highlight" href="#">6</a></td>
<td class=" ui-datepicker-week-end ui-datepicker-days-cell-over bookable ui-datepicker-current-day"
title="This date is available" data-handler="selectDay" data-event="click" data-month="5"
data-year="2020"><a class="ui-state-default ui-state-active" href="#">7</a></td>
</tr>
<tr>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">8</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">9</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">10</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">11</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">12</a></td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">13</a>
</td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">14</a>
</td>
</tr>
<tr>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">15</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">16</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">17</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">18</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">19</a></td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">20</a>
</td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">21</a>
</td>
</tr>
<tr>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">22</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">23</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">24</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">25</a></td>
<td class=" partial_booked bookable"
title="This date is partially booked - but bookings still remain" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">26</a>
</td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">27</a>
</td>
<td class=" ui-datepicker-week-end bookable" title="This date is available" data-handler="selectDay"
data-event="click" data-month="5" data-year="2020"><a class="ui-state-default" href="#">28</a>
</td>
</tr>
<tr>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">29</a></td>
<td class=" bookable" title="This date is available" data-handler="selectDay" data-event="click"
data-month="5" data-year="2020"><a class="ui-state-default" href="#">30</a></td>
<td class=" ui-datepicker-other-month bookable" title="This date is available"
data-handler="selectDay" data-event="click" data-month="6" data-year="2020"><a
class="ui-state-default ui-priority-secondary" href="#">1</a></td>
<td class=" ui-datepicker-other-month bookable" title="This date is available"
data-handler="selectDay" data-event="click" data-month="6" data-year="2020"><a
class="ui-state-default ui-priority-secondary" href="#">2</a></td>
<td class=" ui-datepicker-other-month bookable" title="This date is available"
data-handler="selectDay" data-event="click" data-month="6" data-year="2020"><a
class="ui-state-default ui-priority-secondary" href="#">3</a></td>
<td class=" ui-datepicker-week-end ui-datepicker-other-month bookable"
title="This date is available" data-handler="selectDay" data-event="click" data-month="6"
data-year="2020"><a class="ui-state-default ui-priority-secondary" href="#">4</a></td>
<td class=" ui-datepicker-week-end ui-datepicker-other-month bookable"
title="This date is available" data-handler="selectDay" data-event="click" data-month="6"
data-year="2020"><a class="ui-state-default ui-priority-secondary" href="#">5</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="wc-bookings-date-picker-date-fields" style="display: none;">
<label>
<input type="text" autocomplete="off" name="wc_bookings_field_start_date_month" placeholder="mm" size="2" class="required_for_calculation booking_date_month">
<span>Month</span>
</label> / <label>
<input type="text" autocomplete="off" name="wc_bookings_field_start_date_day" placeholder="dd" size="2" class="required_for_calculation booking_date_day">
<span>Day</span>
</label>
/ <label>
<input type="text" autocomplete="off" value="2020" name="wc_bookings_field_start_date_year" placeholder="YYYY" size="4" class="required_for_calculation booking_date_year">
<span>Year</span>
</label>
</div>
</fieldset>
<div class="form-field form-field-wide">
<div class="block-picker wc-bookings-time-block-picker">
<p>Choose a date above to see available times.</p>
</div>
<input type="hidden" name="wc_bookings_field_duration" value="" class="wc_bookings_field_duration">
<input type="hidden" class="required_for_calculation" name="wc_bookings_field_start_date_time" id="wc_bookings_field_start_date">
</div>
<div class="timezone-details" style="display: none;">
<input type="hidden" name="wc_bookings_field_start_date_local_timezone" value="America/Los_Angeles">
</div>
<div class="wc-bookings-booking-cost" style="display:none" data-raw-price=""></div>
</div>
<div class="wc-deposits-wrapper wc-deposits-optional">
<ul class="wc-deposits-option">
<li>
<input type="radio" name="wc_deposit_option" value="yes" id="wc-option-pay-deposit" checked="checked">
<label for="wc-option-pay-deposit">
Pay Deposit </label>
</li>
<li>
<input type="radio" name="wc_deposit_option" value="no" id="wc-option-pay-full">
<label for="wc-option-pay-full">
Pay in Full </label>
</li>
</ul>
<div class="wc-deposits-payment-description" style="display:block;">
Pay a <span class="wc-deposits-amount">50%%</span> deposit per item </div>
</div>
<input type="hidden" name="add-to-cart" value="4096" class="wc-booking-product-id">
<button type="submit" class="wc-bookings-booking-form-button single_add_to_cart_button button alt disabled" style="">Book now</button>
</form>
</div>
</div>
</div>
CSS
body {
background: white;
color: #323232;
font-weight: 300;
height: 100vh;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-family: Helvetica neue, roboto;
}
img {
width: 56px;
height: 48px;
}
h1 {
font-weight: 200;
font-style: 26px;
margin: 10px;
}
#wc-bookings-booking-form {
background-color: #446084;
border: none;
}
.wc-bookings-date-picker .ui-widget-content {
border: none;
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,0.19);
}
.ui-datepicker table {
width: 100%;
font-size: .9em;
border-collapse: collapse;
margin: 0 0 .4em;
}
tbody {
display: table-row-group;
vertical-align: middle;
border-color: inherit;
}
.wc-bookings-date-picker .ui-datepicker td {
border: none;
border-top: 1px solid #e6e6e6;
border-right: 1px solid #e6e6e6;
background: #fefefe;
padding: 0 !important;
display: table-cell;
}
table td, table th {
padding: 15px;
line-height: 1.5;
vertical-align: top;
border: 1px solid #ccc;
}
.wc-bookings-date-picker .ui-datepicker td .ui-state-default {
background: transparent;
background-image: none !important;
border: none;
color: #2b2b2b;
margin: 0;
font-weight: normal;
text-align: center;
padding: .75em 0;
}
.ui-datepicker td span, .ui-datepicker td a {
display: block;
padding: .2em;
text-align: right;
text-decoration: none;
}
.wc-bookings-date-picker .ui-datepicker td.partial_booked a {
background-color: #2ecc71 !important;
background-image: none !important;
border-color: rgba(0,0,0,0.1) !important;
color: #fff !important;
text-shadow: 0 1px 0 rgba(0,0,0,0.1);
position: relative;
z-index: 1;
}
/*WOOCOMMERCE PARTIALLY BOOKED DAYS CSS*/
.wc-bookings-date-picker .ui-datepicker td.partial_booked a:before {
content: “” !important;
position: absolute !important;
top: 0;
left: 0;
width: 0;
height: 0;
border-top: 2.5em solid #c96259 !important;
border-right: 2.5em solid transparent !important;
z-index: -10 !important;
opacity: .75;
}
2
Answers
Based on LoicTheAztec very helpful answer, here is my final working code:
With WooCommerce Bookings for a “booking” product type on single product pages, to detect the selected day and all related data, you will have to use the delegated event “
date-selected
” like in this example:Code goes in functions.php file of your active child theme (or active theme). Tested and works.