I would like to change the position of all the coupon code-related WooCommerce messages on the checkout page.
I have successfully moved the coupon code form from its original position (top of the checkout page) to after the order details table (woocommerce_review_order_before_payment hook).
But now the coupon code message placement does not make sense, especially for mobile users, therefore I would like to move all of the coupon code-related messages below the coupon form (at the woocommerce_review_order_before_payment hook).
However, it's important that only messages that are related to coupon codes get moved and not all of the messages.
Here's a list of all the WooCommerce messages that are related to coupon codes:
Message
Message type
When
Coupon code already applied!
woocommerce-error
When you try applying a coupon code that has already been applied to your order.
Coupon "coupon-code" does not exist!
woocommerce-error
When you try applying a nonexistent coupon code.
Please enter a coupon code.
woocommerce-error
When you try applying an empty coupon field.
Coupon has been removed.
woocommerce-message
When you successfully remove a coupon code from your order.
Coupon code applied successfully.
woocommerce-message
When you successfully apply a coupon code to your order.
Could someone please help out?
First, As per said #Pavel Vnukov nested forms are not supported and are not part of the w3c standard. so you have added preventDefault so default action should not be taken.
I have fixed some code changes to the #Pavel Vnukov code to work as per your need.
Try the below code.
(function($){
$('.woocommerce-form-coupon-toggle').remove();
$(document).on("click", 'button[name="apply_coupon"]', function(event) {
event.preventDefault();
$form = $('form[name="checkout"]');
$form.block({message:''});
var data = {
security: wc_checkout_params.apply_coupon_nonce,
coupon_code: $( 'input[name="coupon_code"]' ).val()
};
$.ajax({
type: 'POST',
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ),
data: data,
success: function( code ) {
$( '.woocommerce-error, .woocommerce-message' ).remove();
$form.removeClass( 'processing' ).unblock();
if ( code ) {
$( 'button[name="apply_coupon"]' ).parent().after( code );
$( document.body ).trigger( 'update_checkout', { update_shipping_method: false } );
}
},
dataType: 'html'
});
});
})(jQuery);
Tested and Works
It looks like a duplication of Move coupon field after checkout payment in Woocommerce?
Standart coupon form can't be placed before confirmation button - because you will include form in form - nested forms are not supported and are not part of the w3c standard.
You can easily move coupon form after confirmation button. The best way to move coupon block to another place is to use code from above question:
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form');
add_action( 'woocommerce_review_order_before_payment', 'woocommerce_checkout_coupon_form' );
Another way is to remove coupon form from it standard position and create a custom input with a button. Than you need to add custom js code like from woocommerce source (wp-content/plugins/woocommerce/assets/js/frontend/checkout.js:536)
$(".custom_apply_coupon_code").on("click", function(event) {
var data = {
security: wc_checkout_params.apply_coupon_nonce,
coupon_code: $( 'input[name="coupon_code"]' ).val()
};
$.ajax({
type: 'POST',
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ),
data: data,
success: function( code ) {
$( '.woocommerce-error, .woocommerce-message' ).remove();
$form.removeClass( 'processing' ).unblock();
if ( code ) {
$form.before( code );
$form.slideUp();
$( document.body ).trigger( 'update_checkout', { update_shipping_method: false } );
}
},
dataType: 'html'
});
});
Where code will include success or error message.
Related
I want to hide the form after sending the mail in contact form 7. And I want to do another div show with success message in place of the form. Like the screenshot below.
Forms can be hidden with CSS after mail is sent. But I can't do another div show with success message.
.wpcf7-form.sent { display:none; }
you can use the DOM call back wpcf7mailsent in JavaScript to hide the form and show another div.
Basic example
var wpcf7Elm = document.querySelector( '.wpcf7' );
wpcf7Elm.addEventListener( 'wpcf7mailsent', function( event ) {
jQuery(this).hide();
// Some code here to show your custom message element
}, false );
Source
try this code and let me know
var wpcf7Elm = document.querySelector( '.wpcf7' );
wpcf7Elm.addEventListener( 'wpcf7mailsent', function( event ) {
$this = jQuery(this);
$this.children('.ltr_form_area').hide();
$this.children('.ltr_form_success_div').show();
}, false );
I have the following code that triggers whenever the cart is updated.
The problem is that the jQuery version works as expected but the Vanilla JS doesn't.
jQuery( document.body ).on('updated_cart_totals', function( event ) {
console.log( 'in here' ); // Works.
} );
document.body.addEventListener( 'updated_cart_totals', function( event ) {
console.log( 'in here too' ); // Doesn't work.
} );
Is there something I am missing?
It appears to be answered before
https://stackoverflow.com/a/41727891/5454218
jQuery uses its own system of event/data binding which inter-operates only one way. In WooCommerce context it's an essential part of its system, so don't shy away from it. No shame in using jQuery when you're already deep in this pile of s**t.
My Answer would be, Yes it's now possible to detect by addAction() and doAction() using Vanilla JS -
wp.hooks.addAction().
wp.hooks.doAction()
How to do - My Approach
// Trigger any jQuery event
$document.trigger( 'test-trigger', [data] );
// Fire action
wp.hooks.doAction( 'test.trigger', data );
// Catch this event from anywhere in JS
wp.hooks.addAction( 'test.trigger', 'cp/test-trigger', function(data) {
console.log('JS Response data', data);
} , 10);
Reference Example of WordPress Core
For reference, Let's see a WordPress heartbeat js's doAction() - https://github.com/WordPress/wordpress-develop/blob/trunk/src/js/_enqueues/wp/heartbeat.js#L460
// heartbeat.js#L460
$document.trigger( 'heartbeat-tick', [response, textStatus, jqXHR] );
wp.hooks.doAction( 'heartbeat.tick', response, textStatus, jqXHR );
// Catch that heartbeat tick from anywhere in JS
wp.hooks.addAction( 'heartbeat.tick', 'cp/heartbeat-tick', function(response, textStatus, jqXHR) {
console.log('heartbeat response', response);
} , 10, 3);
Adding some jQuery to the WooCommerce checkout page that will hide/show a div based on shipping method (local pickup).
This works initially but due to WooCommerce's ajax loader when switching shipping method the hidden div fades back in when the change has occurred.
I am not sure how to trigger the code again once the switch has happened.
jQuery('form.checkout').on('change','select[name^="shipping_method"]',function() {
var val = jQuery( this ).val();
if (val.match("^local_pickup")) {
jQuery('.flexible-checkout-fields-review_order_before_submit').fadeIn();
} else {
jQuery('.flexible-checkout-fields-review_order_before_submit').fadeOut();
}
});
I expect the div (.flexible-checkout-fields-review_order_before_submit) to only be visible when local pickup is selected, else hide.
Like I say, it works initially, but when you switch the shipping method we are back to square one.
Any thoughts?
I think the issue might be in your first line where you have select[name instead of input[name
Here's some code I use for the same thing so should work for you if you change the name of the element you wish to hide.
I also check and uncheck the ship-to-different-address-checkbox depending on shipping method is selected.
And finally if shipping is required I scroll the page up to the shipping address.
Remove these features if you don't want them.
// When shipping method is selected
jQuery( 'form.checkout' ).on( 'change', 'input[name^="shipping_method"]', function () {
var val = jQuery( this ).val();
if ( val.match( "^local_pickup" ) ) {
jQuery( '#ship-to-different-address-checkbox' ).prop( "checked", false ); // untick shipping checkbox
jQuery( '.shipping_address' ).slideUp(); // hide shipping address
} else {
jQuery( '.shipping_address' ).slideDown(); // show shipping address
jQuery( '#ship-to-different-address-checkbox' ).prop( "checked", true ); // tick shipping checkbox
// scroll to top of shipping address
jQuery('html, body').animate({
scrollTop: jQuery(".shipping_address").offset().top - 120
}, 1500);
}
} );
On the checkout page in Woocommerce there is an "I accept terms and conditions" checkbox. The "terms and conditions" is a link, but Woocommerce captures the click event on the link, and instead opens a small popup(?) with the Terms and conditions page.
I would like to disable the script, and have it be just a normal link.
I identified the js code which captures this event. Unfortunately it's a part of checkout.min.js which controls other parts of the checkout experience too, so I would like to keep the rest of the script intact.
i = {
init: function() {
e(document.body).on("click", "a.woocommerce-terms-and-conditions-link", this.toggle_terms)
},
toggle_terms: function() {
if (e(".woocommerce-terms-and-conditions").length)
return e(".woocommerce-terms-and-conditions").slideToggle(), !1
}
};
i.init()
Bonus question, can I change the link to point to an arbitrary url (a pdf in this case)?
cale_b is right.
But because the link already has target="_blank" there is no need for add a new click handler. To archieve that your custom javascript code is load / run after WooCommerce's script you can use wp_add_inline_script.
I use this snippet and it works:
function disable_wc_terms_toggle() {
wp_add_inline_script( 'wc-checkout', "jQuery( document ).ready( function() { jQuery( document.body ).off( 'click', 'a.woocommerce-terms-and-conditions-link' ); } );" );
}
add_action( 'wp_enqueue_scripts', 'disable_wc_terms_toggle', 1000 );
Add this to your theme's functions.php and your done.
You can also do this by removing the woocommerce 'action'. Add this code to your functions.php file:
function stknat01_woocommerce_checkout_t_c_link() {
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_terms_and_conditions_page_content', 30 );
}
add_action( 'wp', 'stknat01_woocommerce_checkout_t_c_link' )
WooCommerce uses jQuery, so you can use jQuery's off API to remove the event binding, and then assign your own event listener.
Important: The key to making this work is that your script MUST load / run after WooCommerce's script, otherwise the event won't be there to turn "off". If Woo's script runs after yours, it'll bind the event and yours won't remove it. I've demonstrated one method below, but you might need to use others (such as using a setTimeout):
// no-conflict-safe document ready shorthand
jQuery(function($) {
// wait until everything completely loaded all assets
$(window).on('load', (function() {
// remove the click event, and add your own to redirect
$( document.body )
.off( 'click', 'a.woocommerce-terms-and-conditions-link' )
.on( 'click', location.href='your_full_url_here');
});
});
Next, I anticipate you asking how to open the PDF in a new tab - for answers to that, see this question.
I followed this instructions for the removing inline toggle display of "Terms and conditions". It does not work until following code it is removed from checkout.min.js.
.slideToggle(),!1}},i={init:function(){e(document.body).on("click","a.woocommerce-terms-and-conditions-link",this.toggle_terms)},toggle_terms:function(){if(e(".woocommerce-terms-and-conditions").length)return e(".woocommerce-terms-and-conditions").slideToggle(),!1}};
After removing this line from checkout.min.js my checkout.js is also changed, here it is:
//remove toggle
/*
var wc_terms_toggle = {
init: function() {
$( document.body ).on( 'click', 'a.woocommerce-terms-and-conditions-link', this.toggle_terms );
},
toggle_terms: function() {
if ( $( '.woocommerce-terms-and-conditions' ).length ) {
$( '.woocommerce-terms-and-conditions' ).slideToggle();
return false;
}
}
};
*/
// no-conflict-safe document ready shorthand
jQuery(function($) {
// wait until everything completely loaded all assets
$(window).on('load', (function() {
// remove the click event, and add your own to redirect
$( document.body )
.off( 'click', 'a.woocommerce-terms-and-conditions-link' );
.on( 'click', location.href='https://yoursite.whatever');
});
});
wc_checkout_form.init();
wc_checkout_coupons.init();
wc_checkout_login_form.init();
//wc_terms_toggle.init();
});
Thank you for the script.
I want to get the variation price on my single product page, On change the variation drop-down using jQuery, Is there any way to doing this... ?
Thanks in advance.
woocoommerce has build in callback result product details (attributes, price, images, etc..)
you can see variation details on console
jQuery(document).ready(function() {
jQuery( '.variations_form' ).each( function() {
// when variation is found, do something
jQuery(this).on( 'found_variation', function( event, variation ) {
console.log(variation);
console.log(variation.display_price);//selectedprice
});
});
});