skip to Main Content

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.

  1. 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?
  2. Is there a way to do this with pure JS?
  3. 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>&nbsp;<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


  1. Chosen as BEST ANSWER

    Based on LoicTheAztec very helpful answer, here is my final working code:

    /**
     * Add Woocommerce Deposit Cutoff Date
     * Currently set to 9-days in the future.
     * If a user selects a booking date sooner than "10" days from today,
     * Deposit option is set to "pay-in-full" and deposit options are hidden.
     * If a user selects a booking date later than "10" day from today,
     * Deposit option is set to "pay deposit" and deposit options are displayed.
    */
    add_action( 'wp_footer', 'bookable_product_script_js');
    function bookable_product_script_js() {
        global $product;
    
        // Only on single bookable products
        if( is_product() && $product->is_type('booking') ) :
    
        ?>
        <script type='text/javascript'>
        jQuery(function($){
            // Get the date selected value
            $("#wc-bookings-booking-form > fieldset").on('date-selected', function( event, fdate ) {
                console.log( 'Timestamp in seconds: ' + event.timeStamp ); // the selected date timestamp
                console.log( 'Formatted chosen date: ' + fdate ); // The selected formated date in "YYYY-MM-DD" format
    
                var date  = new Date(Date.parse(fdate)), // The selected DATE Object
                    year  = date.getFullYear(), // Year in numeric value with 4 digits
                    month = date.getMonth(), // Month in numeric value from 0 to 11
                    day   = date.getDate(), // Day in numeric value from 1 to 31
                    wDay  = date.getDay(); // Week day in numeric value from 0 to 6
    
                //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() + 9;  
                //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(date <= cuttoffDate) {
                    //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 Cutoff: ', cuttoffDate);
                } else {
                    //set deposit option form field to "pay-in-full"
                    pd = document.getElementById("wc-option-pay-deposit");
                    pd.checked = true;
                    //hide the deposit options
                    document.getElementsByClassName('wc-deposits-wrapper')[0].style.display = 'block';
                    //output for debug
                    //console.log("Deposit allowed");
                }
                //for debug.
                //alert('Years: '+year+' | months: '+month+' | days: '+day+' | week days: '+wDay);
            });
        });
        </script>
        <?php
        endif;
    }
    

  2. 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:

    add_action( 'wp_footer', 'bookable_product_script_js');
    function bookable_product_script_js() {
        global $product;
    
        // Only on single bookable products
        if( is_product() && $product->is_type('booking') ) :
    
        ?>
        <script type='text/javascript'>
        jQuery(function($){
            // Get the date selected value
            $("#wc-bookings-booking-form > fieldset").on('date-selected', function( event, fdate ) {
                console.log( 'Timestamp in seconds: ' + event.timeStamp ); // the selected date timestamp
                console.log( 'Formatted chosen date: ' + fdate ); // The selected formated date in "YYYY-MM-DD" format
    
                var date  = new Date(Date.parse(fdate)), // The selected DATE Object
                    year  = date.getFullYear(), // Year in numeric value with 4 digits
                    month = date.getMonth(), // Month in numeric value from 0 to 11
                    day   = date.getDate(), // Day in numeric value from 1 to 31
                    wDay  = date.getDay(); // Week day in numeric value from 0 to 6
    
                console.log('Year: '+year+' | month: '+month+' | day: '+day+' | week day: '+wDay);
            });
        });
        </script>
        <?php
        endif;
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search