Enable a custom date range datepicker in Woocommerce checkout - php

I have a checkout field and I want to add date ranges instead of picking a single date. Is it possible to use the snippets from jqueryUI to style it and make it a range of dates? I use this function in Woocommerce checkout page on Wordpress.
Below is my current code in the functions.php where I've added the date.
// Register main datepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
}
// Call datepicker functionality in your custom text field
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field', 10, 1);
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('America/Los_Angeles');
$mydateoptions = array('' => __('Select PickupDate', 'woocommerce' ));
echo '<div id="my_custom_checkout_field">
<h3>'.__('Check In Date').'</h3>';
echo '
<script>
jQuery(function($){
$("#datepicker").datepicker();
});
</script>';
woocommerce_form_field( 'order_checkin_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'id' => 'datepicker',
'required' => true,
'label' => __('Check-in Date'),
'placeholder' => __('Select Date'),
'options' => $mydateoptions
),$checkout->get_value( 'order_checkin_date' ));
echo '</div>';
}

This information is available in the jQueryUI documentation. Here's an example of restricting the user to only allow a date 20 days in the past and 1 month + 20 days into the future. Replace your current $("#datepicker").datepicker(); declaration with the following
<script>
jQuery( function() {
$( "#datepicker" ).datepicker({ minDate: -20, maxDate: "+1M +10D" });
} );
</script>

To enable a date range with jQuery-ui Datepicker, there is 2 ways:
With 2 imput text fields that will display a datepicker each with "From" and "To" dates range.
A unique inline date-picker with 2 hidden fields for "from" and "to" dates range, like in this answer.
Here Below based on jQuery-ui datepicker range official documentation, you will be able to set a date range in checkout:
// Register main datepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
}
// Call datepicker functionality in your custom text field
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field', 10, 1);
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('America/Los_Angeles');
?>
<div id="my_custom_checkout_field">
<h3><?php _e('Check In Date'); ?><abbr class="required" title="required">*</abbr></h3>
<?php
woocommerce_form_field( 'order_in_date', array(
'type' => 'text',
'class' => array('form-row-first'),
'id' => 'from',
'required' => true,
'placeholder' => __('Select Date in'),
),$checkout->get_value( 'order_in_date' ));
woocommerce_form_field( 'order_out_date', array(
'type' => 'text',
'class' => array('form-row-last'),
'id' => 'to',
'required' => true,
'placeholder' => __('Select Date out'),
'clear' => true
),$checkout->get_value( 'order_out_date' ));
?>
</div>
<script>
jQuery(function($){
var dateFormat = "yy/mm/dd",
from = $( "#from" ).datepicker().on( "change", function() {
to.datepicker( "option", "minDate", getDate( this ) );
}),
to = $( "#to" ).datepicker().on( "change", function() {
from.datepicker( "option", "maxDate", getDate( this ) );
});
function getDate( element ) {
var date;
try {
date = $.datepicker.parseDate( dateFormat, element.value );
} catch( error ) {
date = null;
}
return date;
}
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Related

How to make a custom field required based on multi countries on WooCommerce checkout?

I am working on multi countries for tax field. Below is my code in woocommerce but it seems not working. However, if i put single country, it works.
Below is the code.
// Add field
function filter_woocommerce_billing_fields( $fields ) {
$fields['billing_vat'] = array(
'label' => 'Tax ID',
'required' => false,
'type' => 'text',
'class' => array( 'form-row-wide' ),
'priority' => 35,
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'filter_woocommerce_billing_fields', 10, 1 );
Validate, i put multi countries here, am i doing wrong?
function action_woocommerce_after_checkout_validation( $data, $error ) {
if ( $data['billing_country'] == 'TW','CN','IE' && empty( $data['billing_vat'] ) ) {
$error->add( 'validation', 'Required based on country.' );
}
}
add_action('woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );
// jQuery
function action_woocommerce_after_order_notes( $checkout ) {
?>
<script>
(function($) {
$(document).ready(function () {
required_or_optional(); //this calls it on load
$( '#billing_country' ).change( required_or_optional );
// i put multi countries here with "or", am i doing wrong?
function required_or_optional() {
if ( $( '#billing_country' ).val() == 'TW' or 'CN' or 'IE' {
// Required
$( '#billing_vat' ).prop( 'required', true );
$( 'label[for="billing_vat"] .optional' ).remove();
$( 'label[for="billing_vat"]' ).append( '<abbr class="required" title="required">*</abbr>' );
} else {
$( '#billing_vat' ).removeProp( 'required' );
$( 'label[for="billing_vat"] .required' ).remove();
// Avoid append this multiple times
if ( $( 'label[for="billing_vat"] .optional' ).length == 0 ) {
$( 'label[for="billing_vat"]' ).append( '<span class="optional">(optional)</span>' );
}
}
}
});
})(jQuery);
</script>
<?php
}
add_action( 'woocommerce_after_order_notes', 'action_woocommerce_after_order_notes', 10, 1 );
// Display on the order edit page (backend)
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
if ( $value = $order->get_meta( '_billing_vat' ) ) {
echo '<p><strong>' . __( 'Billing VAT', 'woocommerce' ) . ':</strong> ' . $value . '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
Should i need to defined the countries in another array? Thx!
I think u overcomplicate it. Try with the following jquery script.
$(document ).on( 'updated_checkout', function() {
add_remove_checkout_fields_conditionaly();
});
function add_remove_checkout_fields_conditionaly() {
var country = $('#billing_country').val();
var compare = ["US", "GB"];
if($.inArray(country,compare)) {
$('#billing_vat_field').addClass('validate-required');
$('#billing_vat_field label span').hide();
$('#billing_vat_field label').append('<abbr class="required" title="">*</abbr>');
} else {
$('#billing_vat_field').removeClass('validate-required');
$('#billing_vat_field label span').show();
$('#billing_vat_field label abbr').hide();
}
}

Dynamic select field, based on Datepicker chosen date issue in Woocommerce

This post is a follow-up on another question:
Dynamic select field options based on selected day in Woocommerce checkout
So, with this answer help, I did manage to build a dynamic select field on the checkout page, which had changing options, based on the chosen date from a Datepicker. This solution works perfectly on the author test server…
However on my site, the code give some problems if the pickeded date is in May or October. Actually it seems that it doesn't work at all.
Those were and are the main requirements:
If Mon-Fri is chosen, pick-up ('delivery_time') every 30 minutes from 10:00 to 18:00
If Sat-Sun is chosen, pick-up ('delivery_time') every 30 minutes from 10:00 to 15:00
Only first Sundays in month is available. Other Sundays, no options available. (new requirement added in April and was working)
Can this have anything to do with my installation? I've tried to disable all plugins and deactivated localizer for Datepicker as well.
Following is the code for Dynamic select:
/**
*
* 2018-04-16
* Picking date and time
* Dynamic select based on selected day
*
*/
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
wp_enqueue_style('jquery-ui', "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css", '', '', false);
}
// Datepicker field and select time field
add_action( 'woocommerce_before_order_notes', 'datepicker_custom_field' );
function datepicker_custom_field($checkout) {
echo '<h3>' . __('Hvornår vil du hente din ordre?') . '</h3>';
echo '<div id="date-time-wrapper">';
woocommerce_form_field('delivery_date', array(
'type' => 'text',
'class'=> array('delivery-date-class form-row-first'),
'label' => __('Vælg dato for afhentning'),
'required' => true,
//'placeholder' => __('Pick a date')
), $checkout->get_value('delivery_date') );
$options = array('' => __('Afhentning kl.') );
woocommerce_form_field( 'delivery_time', array(
'type' => 'select',
'class' => array('delivery-time-class form-row-last'),
'label' => __('Vælg tidspunkt for afhentning'),
'required' => true,
'options' => $options,
), $checkout->get_value( 'delivery_time' ) );
// Restricted options array
$options1 = array(
'10:00' => __( '10:00' ),
'10:30' => __( '10:30' ),
'11:00' => __( '11:00' ),
'11:30' => __( '11:30' ),
'12:00' => __( '12:00' ),
'12:30' => __( '12:30' ),
'13:00' => __( '13:00' ),
'13:30' => __( '13:30' ),
'14:00' => __( '14:00' ),
'14:30' => __( '14:30' ),
'15:00' => __( '15:00' ),
);
// The other part of options array
$options2 = array(
'15:30' => __( '15:30' ),
'16:00' => __( '16:00' ),
'16:30' => __( '16:30' ),
'17:00' => __( '17:00' ),
'17:30' => __( '17:30' ),
'18:00' => __( '18:00' ),
);
// The third part of options array
$options3 = array(
'Sundays_Closed' => __( 'Åbent første søndag i måneden'),
);
// Merging options arrays
$options1 = array_merge($options, $options1); // Partial
$options = array_merge($options1,$options2); // Full
echo '<br clear="all"></div>';
?>
<script language="javascript">
jQuery( function($){
var a = <?php echo json_encode($options); ?>,
b = <?php echo json_encode($options1); ?>,
e = <?php echo json_encode($options3); ?>,
c = new Date(),
s = 'select#delivery_time';
// Utility function to fill dynamically the select field options
function dynamicSelectOptions( opt ){
var o = '';
$.each( opt, function( key, value ){
o += '<option value="'+key+'">'+value+'</option>';
});
$(s).html(o);
}
// Once DOM is loaded
//Only open first Sunday in month
if( c.getDay() == 0 && c.getDate() > 7 ){
dynamicSelectOptions( e );
}
else if( c.getDay() == 6 || c.getDay() == 0){
dynamicSelectOptions( b );
}
else
dynamicSelectOptions( a );
// Select time to selectWoo
$(s).selectWoo();
// Datepicker
$('#delivery_date').datepicker({
dateFormat: 'd MM, y',
minDate:1,
maxDate:new Date(2018, 12),
onSelect: function(){
// Live event: On selected date event
var d = new Date($(this).val());
//Only first Sunday in month open
if( d.getDay() == 0 && d.getDate() > 7 ){
dynamicSelectOptions( e );
}
else if( d.getDay() == 6 || d.getDay() == 0){
dynamicSelectOptions( b );
}
else
dynamicSelectOptions( a );
}
}).parent().after('<div id="order-desc"></div>');
});
</script>
<?php
}
I have made some little changes in your code:
I Have moved the jQuery script in footer at the end (as it's the best way for jQuery).
I have embed all your select options (all different arrays) in a separate utility function.
But I am not sure that it will work on your server configuration... I hope that this will solve the problem (that I don't have on my both test servers configs).
Your code revisited code:
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
wp_enqueue_style('jquery-ui', "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css", '', '', false);
}
// Utility function (with all option arrays)
function select_options( $type = '' ){
$options = array('' => __('Afhentning kl.') ); // Default start
$options1 = array( // Restricted options array
'10:00' => __( '10:00' ), '10:30' => __( '10:30' ), '11:00' => __( '11:00' ),
'11:30' => __( '11:30' ), '12:00' => __( '12:00' ), '12:30' => __( '12:30' ),
'13:00' => __( '13:00' ), '13:30' => __( '13:30' ), '14:00' => __( '14:00' ),
'14:30' => __( '14:30' ), '15:00' => __( '15:00' ),
);
$options2 = array( // complementary options array
'15:30' => __( '15:30' ), '16:00' => __( '16:00' ), '16:30' => __( '16:30' ),
'17:00' => __( '17:00' ), '17:30' => __( '17:30' ),'18:00' => __( '18:00' ),
);
if( $type == 'partial' ){
return array_merge($options, $options1); // Partial;
} elseif ( $type == 'full' ){
return array_merge($options,$options1,$options2); // Full
} elseif ( $type == 'close' ){
return array( 'Sundays_Closed' => __( 'Åbent første søndag i måneden') ); // Sundays closed
} else {
return $options; // Default (start)
}
}
// Checkout Datepicker field and select time field
add_action( 'woocommerce_before_order_notes', 'datepicker_custom_field' );
function datepicker_custom_field($checkout) {
echo '<h3>' . __('Hvornår vil du hente din ordre?') . '</h3>';
echo '<div id="date-time-wrapper">';
woocommerce_form_field('delivery_date', array(
'type' => 'text',
'class'=> array('delivery-date-class form-row-first'),
'label' => __('Vælg dato for afhentning'),
'required' => true,
//'placeholder' => __('Pick a date')
), $checkout->get_value('delivery_date') );
$options = select_options();
woocommerce_form_field( 'delivery_time', array(
'type' => 'select',
'class' => array('delivery-time-class form-row-last'),
'label' => __('Vælg tidspunkt for afhentning'),
'required' => true,
'options' => $options,
), $checkout->get_value( 'delivery_time' ) );
echo '<br clear="all"></div>';
}
add_action( 'wp_footer', 'date_picker_js_script' );
function date_picker_js_script() {
// Only on checkout page
if( ! is_checkout() ) return;
?>
<script language="javascript">
jQuery( function($){
var a = <?php echo json_encode(select_options('full')); ?>,
b = <?php echo json_encode(select_options('partial')); ?>,
e = <?php echo json_encode(select_options('close')); ?>,
c = new Date(),
s = 'select#delivery_time';
// Utility function to fill dynamically the select field options
function dynamicSelectOptions( opt ){
var o = '';
$.each( opt, function( key, value ){
o += '<option value="'+key+'">'+value+'</option>';
});
$(s).html(o);
}
// ===> Just for testing - To be removed
console.log('Day: '+c.getDay()+' | Date: '+c.getDate());
// 1. Once DOM is loaded
if( c.getDay() == 0 && c.getDate() > 7 ){ // Only open first Sunday in month
dynamicSelectOptions( e );
} else if( c.getDay() == 6 || c.getDay() == 0){ // Weekends
dynamicSelectOptions( b );
} else { // all others days
dynamicSelectOptions( a );
}
// Select time to selectWoo
$(s).selectWoo();
// Datepicker
$('#delivery_date').datepicker({
dateFormat: 'd MM, y',
minDate:1,
maxDate:new Date(2018, 12),
onSelect: function(){
// On live calendar event: On selected date event
var d = new Date($(this).val());
// ===> Just for testing - To be removed
console.log('Day: '+d.getDay()+' | Date: '+d.getDate());
if( d.getDay() == 0 && d.getDate() > 7 ) { // Only first Sunday in month open
dynamicSelectOptions( e );
} else if( d.getDay() == 6 || d.getDay() == 0) { // Weekends
dynamicSelectOptions( b );
} else { // all others days
dynamicSelectOptions( a );
}
}
}).parent().after('<div id="order-desc"></div>');
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme).
I have tested your code on 2 different test servers with WooCommerce 3.2.x and 3.3.x, and it works (tested that on different browsers and platforms).
This issue could be related to your theme, some plugin or other customizations made by you.

Hide shipping method based on the radio button in WooCommerce checkout page

I put a radio button in the checkout page with the code below.
add_action( 'woocommerce_before_checkout_shipping_form', 'custom_shipping_radio_button', 10, 1 );
function custom_shipping_radio_button( $checkout ) {
woocommerce_form_field( 'shipping_type', array(
'type' => 'radio',
'class' => array( 'form-row-wide' ),
'label' => __('收件方式 *'),
'options' => array(
'shipping_1' => __('全家店到店'),
'shipping_2' => __('指定地址'),
'shipping_3' => __('自行取貨'),
),
), $checkout->get_value( 'shipping_type' ) );
}
I want to hide the option based on shipping method. For example, if the customers choose local pickup, options, shipping_1 and shipping_2 will disappear. I searched some information and tried to make the codes as below.
add_action( 'woocommerce_after_checkout_form', 'hide_shipping_type' );
function hide_shipping_type( $available_gateways ) {
global $woocommerce;
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping_no_ajax = $chosen_methods[0];
if ( 0 === strpos( $chosen_shipping_no_ajax, 'local_pickup' ) ) {
?>
<script type="text/javascript">
jQuery('#shipping_type_shipping_1,#shipping_type_shipping_2').fadeOut();
</script>
<?php
}
?>
<script type="text/javascript">
jQuery('form.checkout').on('change','input[name^="shipping_method"]',function() {
var val = jQuery( this ).val();
if (val.match("^local_pickup")) {
jQuery('#shipping_type_shipping_1,#shipping_type_shipping_2').fadeOut();
} else {
jQuery('#shipping_type_shipping_1,#shipping_type_shipping_2').fadeIn();
}
});
</script>
<?php
}
I found that the labels for the options cannot be hidden. I thought the problem may be caused by jQuery script. However, I cannot make it better.
Does anybody have idea about this problem?
UPDATE
I got a new idea about unsetting shipping method in cart page and hiding shipping method in checkout page based on shipping type radio button. As a result, I tried to write the code as below. These codes can work and the label of shipping method can disappear. However, after selecting the one of shipping methods, the other hide shipping methods will fade in. Is there any solution?
//Unset shipping method in cart page
add_filter( 'woocommerce_cart_ready_to_calc_shipping', 'disable_shipping_calc_on_cart', 99 );
function disable_shipping_calc_on_cart( $show_shipping ) {
if( is_cart() ) {
return false;
}
return $show_shipping;
}
//Hide shipping method in checkout page based on the selection of radio button.
add_action( 'woocommerce_before_checkout_shipping_form', 'custom_shipping_radio_button', 10, 1 );
function custom_shipping_radio_button( $checkout ) {
woocommerce_form_field( 'shipping_type', array(
'type' => 'radio',
'class' => array( 'form-row-wide' ),
'label' => __('收件方式 *'),
'options' => array(
'shipping_1' => __('全家店到店'),
'shipping_2' => __('指定地址'),
'shipping_3' => __('自行取貨'),
),
), $checkout->get_value( 'shipping_type' ) );
?>
<script type="text/javascript">
jQuery(function($){
$("input[name=shipping_type]").on("change",function(){
if($("#shipping_type_shipping_1").is(":checked")) {
$("#add_familimart,#shipping_first_name_field,#shipping_last_name_field,#shipping_city_field,#shipping_company_field,#shipping_method_0_flat_rate9,label[for='shipping_method_0_flat_rate9']").fadeIn();
} else {
$("#add_familimart,#shipping_first_name_field,#shipping_last_name_field,#shipping_city_field,#shipping_company_field,#shipping_method_0_flat_rate9,label[for='shipping_method_0_flat_rate9']").fadeOut();
}
if($("#shipping_type_shipping_2").is(":checked")) {
$("#shipping_postcode_field,#shipping_address_1_field,#shipping_method_0_flat_rate10,#shipping_method_0_flat_rate11,#shipping_method_0_flat_rate12,label[for='shipping_method_0_flat_rate12'],label[for='shipping_method_0_flat_rate11'],label[for='shipping_method_0_flat_rate10']").fadeIn();
} else {
$("#shipping_postcode_field,#shipping_address_1_field,#shipping_method_0_flat_rate10,#shipping_method_0_flat_rate11,#shipping_method_0_flat_rate12,label[for='shipping_method_0_flat_rate12'],label[for='shipping_method_0_flat_rate11'],label[for='shipping_method_0_flat_rate10']").fadeOut();
}
if($("#shipping_type_shipping_3").is(":checked")) { $("#shipping_address_2_field,#shipping_method_0_local_pickup8,label[for='shipping_method_0_local_pickup8']").fadeIn();
} else {
$("#shipping_address_2_field,#shipping_method_0_local_pickup8,label[for='shipping_method_0_local_pickup8']").fadeOut();
}
});
});
</script>
<?php
}
You can merge all your code in the first function and it work as well. Now you should need to add jQuery ready() function at start.
It's quiet simple and easy to target <label> tags with a "for" attribute using in your case label[for="shipping_type_shipping_1"] and label[for="shipping_type_shipping_2"]…
I have revisited and compacted your code in one unique hooked function:
add_action( 'woocommerce_before_checkout_shipping_form', 'custom_shipping_radio_buttons', 10, 1 );
function custom_shipping_radio_buttons( $checkout ) {
woocommerce_form_field( 'shipping_type', array(
'type' => 'radio',
'class' => array( 'form-row-wide' ),
'label' => __('收件方式 *'),
'options' => array(
'shipping_1' => __('全家店到店'),
'shipping_2' => __('指定地址'),
'shipping_3' => __('自行取貨'),
),
), $checkout->get_value( 'shipping_type' ) );
$chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' )[0];
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
var a = 'shipping_type_shipping_',
b = 'label[for="'+a+'1"],label[for="'+a+'2"],#'+a+'1,#'+a+'2';
<?php if ( 0 === strpos( $chosen_shipping_methods, 'local_pickup' ) ): ?>
$(b).fadeOut(); // Once DOM is loaded
<?php endif; ?>
// On live "change event
$('form.checkout').on('change','input[name^="shipping_method"]',function() {
var c = $(this).val();
if ( c.match('^local_pickup') )
$(b).fadeOut();
else
$(b).fadeIn();
});
});
</script>
<?php
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works. It shows / hide the 2 radio buttons + their labels, depending if "local_pickup" is the chosen Shipping Method…
Update (related to your comment)
May be you should try something like this:
add_action( 'woocommerce_before_checkout_shipping_form', 'custom_shipping_radio_buttons', 10, 1 );
function custom_shipping_radio_buttons( $checkout ) {
woocommerce_form_field( 'shipping_type', array(
'type' => 'radio',
'class' => array( 'form-row-wide' ),
'label' => __('收件方式 *'),
'options' => array(
'shipping_1' => __('全家店到店'),
'shipping_2' => __('指定地址'),
'shipping_3' => __('自行取貨'),
),
), $checkout->get_value( 'shipping_type' ) );
// HERE below define your shipping "flat rates" method IDs in the array
$other_method_ids = array( 'flat_rate:09', 'flat_rate:10', 'flat_rate:11', 'flat_rate:12' );
$local_pickup = 'local_pickup';
// Get the chosen shipping method
$chosen_shipping = WC()->session->get( 'chosen_shipping_methods' )[0];
// Get the chosen shipping method ID
$chosen_shipping_expl = explode( ':', $chosen_shipping );
$chosen_method_id = $chosen_shipping_expl[0];
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
var a = 'shipping_type_shipping_',
b = 'label[for="'+a+'1"],label[for="'+a+'2"],#'+a+'1,#'+a+'2',
c = <?php echo json_encode( $other_method_ids ); ?>; // array of shipping methods ids
// Once DOM is loaded
<?php if ( $chosen_method_id === $local_pickup || in_array( $chosen_shipping, $other_method_ids) ): ?>
$(b).fadeOut();
<?php endif; ?>
// On live "change event
$('form.checkout').on('change','input[name^="shipping_method"]',function() {
var d = $(this).val();
console.log(e);
if ( e.match('^local_pickup') || $.inArray(d, c) !== -1 )
$(b).fadeOut();
else
$(b).fadeIn();
});
});
</script>
<?php
}
Tested and works.
I tried to add the codes for the other options with your codes. However, it cannot works well.
$chosen_shipping_methods_2 = WC()->session->get( 'chosen_shipping_methods' )[0];
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
var d = 'shipping_type_shipping_',
e ='label[for="'+d+'2"],label[for="'+d+'3"],#'+d+'2,#'+d+'3';
<?php if ( 0 === strpos( $chosen_shipping_methods_2, 'flat_rate:9' ) ): ?>
$(e).fadeOut(); // Once DOM is loaded
<?php endif; ?>
// On live "change event
$('form.checkout').on('change','input[name^="shipping_method"]',function() {
var f = $(this).val();
if ( f.match('^flat_rate:9') )
$(e).fadeOut();
else
$(e).fadeIn();
});
});
</script>
<?php
$chosen_shipping_methods_3 = WC()->session->get( 'chosen_shipping_methods' )[0];
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
var g = 'shipping_type_shipping_',
h = 'label[for="'+g+'1"],label[for="'+g+'3"],#'+g+'1,#'+g+'3';
<?php if ( 0 === strpos( $chosen_shipping_methods_3, 'flat_rate:10', 'flat_rate:11', 'flat_rate:12' ) ): ?>
$(h).fadeOut(); // Once DOM is loaded
<?php endif; ?>
// On live "change event
$('form.checkout').on('change','input[name^="shipping_method"]',function() {
var i = $(this).val();
if ( i.match('^flat_rate:10', '^flat_rate:11', '^flat_rate:12') )
$(h).fadeOut();
else
$(h).fadeIn();
});
});
</script>
<?php

Enable Datepicker in a WooCommerce Checkout custom text field

In WooCommerce, I can get a field hooked into my WooCommerce cart page & showing up OK using the following in my theme's (Storefront) functions PHP:
<?
// ADD Custom Fields to Checkout Page
/**
* Add the field to the checkout
**/
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('America/Los_Angeles');
$mydateoptions = array('' => __('Select PickupDate', 'woocommerce' ));
echo '<div id="my_custom_checkout_field"><h3>'.__('Delivery Info').'</h3>';
woocommerce_form_field( 'order_pickup_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'id' => 'datepicker',
'required' => true,
'label' => __('Delivery Date'),
'placeholder' => __('Select Date'),
'options' => $mydateoptions
),$checkout->get_value( 'order_pickup_date' ));
echo '</div>';
}
/**
* Process the checkout
**/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if (!$_POST['order_pickup_date'])
wc_add_notice( '<strong>PickupDate</strong> ' . __( 'is a required field.', 'woocommerce' ), 'error' );
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['order_pickup_date']) update_post_meta( $order_id, 'PickupDate', esc_attr($_POST['order_pickup_date']));
}
?>
However, the datepicker widget is not initiated when you click into the field. I know the following code is required in the header for JQuery to work:
<script>
$( function() {
$( "#datepicker" ).datepicker(); } );
</script>
This did not work for me, so I thought to put this function into the checkout.js file in Storefront theme, but the added field didn't have calendar widget functionality.
There's a lot of .js in the them do I need to start a new one for includes?
First you will need to:
Enqueu main jquery-ui datepicker script
Change your custom script starting it with jQuery(function($){ instead of $(function(){ …
So to enable datepicker for your custom text field your code will be:
// Register main datepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
}
// Call datepicker functionality in your custom text field
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field', 10, 1);
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('America/Los_Angeles');
$mydateoptions = array('' => __('Select PickupDate', 'woocommerce' ));
echo '<div id="my_custom_checkout_field">
<h3>'.__('Delivery Info').'</h3>';
// YOUR SCRIPT HERE BELOW
echo '
<script>
jQuery(function($){
$("#datepicker").datepicker();
});
</script>';
woocommerce_form_field( 'order_pickup_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'id' => 'datepicker',
'required' => true,
'label' => __('Delivery Date'),
'placeholder' => __('Select Date'),
'options' => $mydateoptions
),$checkout->get_value( 'order_pickup_date' ));
echo '</div>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. On storefront theme you will get that:
You may need to style it…
Just an update that this is no longer necessary. With Woocommerce you can simply change the style to 'date' and it deals with the rest for you - yahoo!

Woocommerce Local Pickup Plus - modify to force all items to be picked up

I am working with the Local Pickup Plus plugin for woocommerce and it is almost everything that I need, except for the fact that the customer has to manually select every product in the cart as either shipping or local pickup.
I was wondering if there was an easy way to force the customer to have all items shipped or all items picked up
I ended up solving this by writing my own function to only do what I was specifically looking for. This function adds the option to select from a drop down which store to pickup from and then updates the shipping accordingly.
/**
* Add store location select dropdown in checkout page
**/
add_filter( 'woocommerce_checkout_fields' , 'custom_store_pickup_field');
function custom_store_pickup_field( $fields ) {
$fields['billing']['store_pickup'] = array(
'type' => 'select',
'options' => array(
'option_0'=> 'Please Select a Delivery Option',
'option_1' => 'Delivery',
'option_2' => 'Gym1',
'option_3' => 'Gym2'
),
'label' => __('Delivery or Store Pickup', 'woocommerce'),
'required' => true,
'class' => array('store-pickup form-row-wide'),
'id' => 'store_pickup_val',
'clear' => true
);
return $fields;
}
//* Process the checkout
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['store_pickup'] == "option_0")
wc_add_notice( '<strong>Please select a day part under Delivery options</strong>', 'error' );
}
add_action( 'woocommerce_after_checkout_form', 'gym_opening_hours', 6);
function gym_opening_hours() {
?>
<script type="text/javascript">
jQuery('#store_pickup_val').change(function(){
jQuery('body').trigger('update_checkout');
jQuery( ".gym-collection" ).remove();
if (this.value == 'option_1') {
jQuery('#shipping_method_0_flat_rate1').prop('checked', true);
}
if (this.value == 'option_2') {
jQuery( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
jQuery('#shipping_method_0_local_pickup3').prop('checked', true);
}
if (this.value == 'option_3') {
jQuery( "<p>Order can be collected between 4pm - 7pm on Tuesdays</p>" ).addClass("gym-collection").insertAfter( "#store_pickup_val" );
jQuery('#shipping_method_0_local_pickup3').prop('checked', true);
}
else {
}
});
</script>
<?php
}
# add this in your plugin file and that's it, the calculate_shipping method of your shipping plugin class will be called again
function action_woocommerce_checkout_update_order_review($array, $int)
{
WC()->cart->calculate_shipping();
return;
}
add_action('woocommerce_checkout_update_order_review', 'action_woocommerce_checkout_update_order_review', 10, 2);
?>
<?php

Categories