I am wondering if someone can help me with the following code. I am trying to set some conditional html dependent on which payment method the user selects on checkout. On the payment method page I am using the following function to update the payment method information:
function cart_update_script() {
if (is_checkout()) :
?>
<script>
jQuery( function( $ ) {
// woocommerce_params is required to continue, ensure the object exists
if ( typeof woocommerce_params === 'undefined' ) {
return false;
}
$checkout_form = $( 'form.checkout' );
$checkout_form.on( 'change', 'input[name="payment_method"]', function() {
$checkout_form.trigger( 'update' );
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'cart_update_script', 999 );
On the final checkout page I am then getting that selected payment method with this bit of code:
<?php $chosen_gateway = WC()->session->chosen_payment_method; ?>
Then I am using conditional statements like the following:
<?php if ( $chosen_gateway == 'stripe' ) { ?>
//do this
<?php } ?>
My problem is that I am not getting dynamic information when the user changes payment method. Sometimes the code works but sometimes it still thinks a different payment method was selected. Any help would be great!
Related
I have a PHP function (which contains jQuery) at the checkout page that hides one checkbox if another is not checked (all works fine).
/***START - SHOW HIDE DEPOSIT CHECKBOX***/
function action_wp_footerr() {
// Only on checkout
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script type="text/javascript">
jQuery( function($){
// Selector
var my_input = $(".forwarding");
var my_depo = '#my_id_field';
// Show or hide
function show_or_hide() {
if ( $( my_input ).is(':checked') ) {
return $( my_depo ).show();
} else {
$( my_depo ).hide();
$( "#my_id" ).prop( "checked", false );
}
}
// Default
$( document ).ajaxComplete(function() {
show_or_hide();
});
// On change
$( 'form.checkout' ).change(function() {
show_or_hide();
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'action_wp_footerr', 10, 0 );
/***END - SHOW HIDE DEPOSIT CHECKBOX***/
Current if statement is as follows:
if ( is_checkout() && ! is_wc_endpoint_url() ) :
I need to add a condition to this if statement where the total order value needs to be greater than 1800.
To get the order total I use:
$total = $order->get_total();
Further, I add another variable that contains the value of 1800
$value = 1800;
Now I try to add this condition to the current if statement
if ( is_checkout() && ! is_wc_endpoint_url() && $total > $value ) :
However, now the function does not work and the frontend gets distorted.
How to add this condition properly?
The requirement:
Depending on the chosen payment option, certain checkout fields should not be required.
My scenario:
It clients select "local pickup" they get the option to select PayPal, credit card etc. and "pay at pickup".
If they pay at pickup, we don't need they payment address. The invoice will be handled at pickup and the checkout is actually a reservation.
I have found a solution myself and share this question as a reference.
Find the solution in an answer.
This is my solution:
add_action( 'woocommerce_checkout_process', 'gw_deactivate_some_fields_on_condition');
function gw_deactivate_some_fields_on_condition() {
add_filter( 'woocommerce_checkout_fields' , 'gw_some_billing_fields_not_required_for_cash_on_delivery_payment_method' );
}
function gw_some_billing_fields_not_required_for_cash_on_delivery_payment_method( $fields ) {
$chosen_payment_method = WC()->session->get('chosen_payment_method');
if ( 0 === strpos( $chosen_payment_method, 'cash_on_delivery' ) ) {
$fields['billing']['billing_address_1']['required'] = false;
$fields['billing']['billing_address_2']['required'] = false;
$fields['billing']['billing_city']['required'] = false;
$fields['billing']['billing_postcode']['required'] = false;
$fields['billing']['billing_country']['required'] = false;
$fields['billing']['billing_state']['required'] = false;
}
return $fields;
}
add_action( 'woocommerce_after_checkout_form', 'gw_disable_payment_fields_if_local_payment' );
function gw_disable_payment_fields_if_local_payment( $available_gateways ) {
?>
<script type="text/javascript">
jQuery( document ).ready(function() {
show_hide_payment_options();
});
jQuery('form.checkout').on('change','input[name^="payment_method"]',function() {
show_hide_payment_options();
});
jQuery('form.checkout').on('change','input[name^="shipping_method"]',function() {
show_hide_payment_options();
});
function show_hide_payment_options() {
var val = jQuery('input[name^="payment_method"]:checked').val(); // If it changed, then it must be the radio options so check the one that's selected
var fields_selector = '#billing_country_field, #billing_address_1_field, #billing_address_2_field, #billing_city_field, #billing_postcode_field';
if (val.match("^cash_on_delivery")) {
jQuery( fields_selector ).fadeOut();
} else {
jQuery( fields_selector ).fadeIn();
}
}
</script>
<?php
}
For handling the shipping fields see this post:
https://www.businessbloomer.com/woocommerce-hide-shipping-local-pickup-selected/
This was also a strong inspiration for my code.
I'm trying to show/hide some elements from my checkout page, based on the chosen shipping method. The page elements I'm trying to show/hide come from another plugin, so I tried to change the display properties for them. I've looked to many thread like:
Show or hide checkout fields based on shipping method in Woocommerce 3
But it's for checkout fields, and I'm not sure how to do it for page elements.
Then based on this answer thread Here's my code so far:
add_action( 'wp_footer', 'conditionally_hidding_order_delivery_date' );
function conditionally_hidding_order_delivery_date(){
// Only on checkout page
if( ! is_checkout() ) return;
// HERE your shipping methods rate ID "Home delivery"
$home_delivery = 'distance_rate_shipping';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var shipMethod = 'input[name^="shipping_method"]',
shipMethodChecked = shipMethod+':checked';
// Function that shows or hide imput select fields
function showHide( actionToDo='show', selector='' ){
if( actionToDo == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Initialising: Hide if choosen shipping method is "Home delivery"
if( $(shipMethodChecked).val() != '<?php echo $home_delivery; ?>' ) {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
// Live event (When shipping method is changed)
$( 'form.checkout' ).on( 'change', shipMethod, function() {
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' ) {
showHide('show','#e_deliverydate_field' );
showHide('show','#time_slot_field' );
}
else {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
});
});
</script>
<?php
}
But it's not working completely (the initializing function is not working.)
Any help is very much appreciated.
Additional edit:
<p class="form-row form-row-wide validate-required" id="e_deliverydate_field" data-priority="" style="display: block;"><label for="e_deliverydate" class="">Date<abbr class="required" title="required">*</abbr></label><span class="woocommerce-input-wrapper"><input class="input-text hasDatepicker" name="e_deliverydate" id="e_deliverydate" placeholder="Choose a Date" value="" style="cursor:text !important;" type="text"></span></p>
My objective is to change the display properties for p element from block to none, and vice versa.
The needed code is something much more simple, than the one used in my other answers, but you need to be sure that the targeted chosen shipping method is 'distance_rate_shipping' as I can't test it.
For initialization problem, see the solution exposed at the end of my answer.
The simplified needed code:
// Embedded jQuery script
add_action( 'wp_footer', 'checkout_delivery_date_script' );
function checkout_delivery_date_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input[name^="shipping_method"]', b = a+':checked',
c = 'distance_rate_shipping',
d = '#e_deliverydate_field,#time_slot_field';
// Utility function that show or hide the delivery date
function showHideDeliveryDate(){
if( $(b).val() == c )
$(d).show();
else
$(d).hide('fast');
console.log('Chosen shipping method: '+$(b).val()); // <== Just for testing (to be removed)
}
// 1. On start
showHideDeliveryDate();
// 2. On live event "change" of chosen shipping method
$('form.checkout').on('change', a, function(){
showHideDeliveryDate();
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or theme). It should work.
The initialization problem:
It's certainly because the plugin you are using that generates the delivery date output is delayed after initialization
The solution can be to add some delay on initialization execution.
So should try to replace this:
// 1. On start
showHideDeliveryDate();
By the following in my code (adjusting the execution delay to something higher or lower than 500):
// 1. On start
setTimeout(function(){
showHideDeliveryDate();
}, 500);
I am looking for a solution on wordpress contact form7.
either a plugin or in PHP code.
I am not looking for JavaScript solution. as I have already found JavaScript solution. Again: I am looking for either plugin or PHP code.
I want to use one form (CF7) and it will redirect to multiple thank you pages based on from which page the form submitted.
Below example code.
if is_page(1){
contact-form will go to thank-you-page-1
} else if is_page(2) {
contact-form will go to thank-you-page-2
}
You can do by this hook
add_action('wpcf7_mail_sent', function ($cf7) {
// Run code after the email has been sent
$wpcf = WPCF7_ContactForm::get_current();
$wpccfid=$wpcf->id;
// if you wanna check the ID of the Form $wpcf->id
if ( '34' == $wpccfid ) { // Change 123 to the ID of the form
//you can use also if(is_page()){} condition
//redirect to url
wp_redirect('url of thank you page');
exit();
}
}
<?php if (is_page(array(1))) { ?>
<script type="text/javascript">
document.addEventListener( 'wpcf7mailsent', function( event ) {
location = 'https://page-link-1.com/';
}, false );
</script>
<?php } else if ( is_page(array(2))) { ?>
<script type="text/javascript">
document.addEventListener( 'wpcf7mailsent', function( event ) {
location = 'https://page-link-2.com/';
}, false );
</script>
<?php } ?>
I am using woocommerce plugin and braintree extension of woocommerce for payment. I have enabled both card and paypal payment of woocommerce braintree to checkout. I am trying to figure out how to know which payment gateway the user selects before user actually checkouts and pays. Any hooks under woocommerce or braintree to find either credit card radio button or paypal payment radio button is checked for payment.
However i know we can detect the gateway used for the particular order after successful payment but i want the selected gateway information before payment completes within checkout page. Any Help?
You can detect chosen Payment Method with some basic JavaScript on checkout page and run your custom code with PHP by hooking into woocommerce_checkout_update_order_review action.
First,
you also should place JS code on checkout page, checkout template or in header/footer of your theme, so you can detect when the user has changed payment method option and run your own code after that.
JS code:
jQuery(document).ready( function() {
jQuery( "#payment_method_bacs" ).on( "click", function() {
jQuery( 'body' ).trigger( 'update_checkout' );
});
jQuery( "#payment_method_paypal" ).on( "click", function() {
jQuery(document.body).trigger("update_checkout");
});
jQuery( "#payment_method_stripe" ).on( "click", function() {
jQuery(document.body).trigger("update_checkout");
});
});
Notice that for each payment method you have active you should add 'Click' event. It gives you option to fine tune when your custom code is triggered.
To prevent click event to run ONLY ONCE you should add next block of JS code below first one.
jQuery( document ).ajaxStop(function() {
jQuery( "#payment_method_bacs" ).on( "click", function() {
jQuery(document.body).trigger("update_checkout");
});
jQuery( "#payment_method_paypal" ).on( "click", function() {
jQuery(document.body).trigger("update_checkout");
});
jQuery( "#payment_method_stripe" ).on( "click", function() {
jQuery(document.body).trigger("update_checkout");
});
});
It's the same code only that is triggered after ajax.
In both JS blocks of code add your payment options that you are actually use.
After that you put your custom PHP code that hooks into checkout like this:
if ( ! function_exists( 'name_of_your_function' ) ) :
function name_of_your_function( $posted_data) {
// Your code goes here
}
endif;
add_action('woocommerce_checkout_update_order_review', 'name_of_your_function');
This code can be placed in functions.php.
Here is complete PHP code that detects and run when specific payment option is chosen on checkout page:
function name_of_your_function( $posted_data) {
global $woocommerce;
// Parsing posted data on checkout
$post = array();
$vars = explode('&', $posted_data);
foreach ($vars as $k => $value){
$v = explode('=', urldecode($value));
$post[$v[0]] = $v[1];
}
// Here we collect payment method
$payment_method = $post['payment_method'];
// Run code custom code for each specific payment option selected
if ($payment_method == "paypal") {
// Your code goes here
}
elseif ($payment_method == "bacs") {
// Your code goes here
}
elseif ($payment_method == "stripe") {
// Your code goes here
}
}
add_action('woocommerce_checkout_update_order_review', 'name_of_your_function');
I hope this helps!
This is a very powerful option to run all your custom logic on the checkout page!