How to refresh cart and checkout in every 5 seconds in WooCommerce? - wordpress

I am working on WordPress / WooCommerce
My requirement is when the customer is on the CART page, I want to refresh CART every 5 seconds, without page load.
For eg: If the customer has added 1 product to the cart and the price is ₹8.00
Later on, Admin changes the price for the product from ₹8.00 to ₹10.00
How can I show the latest price without page refresh?
I am using this code, but not working
(function( $ ) {
'use strict';
jQuery( document ).ready(function($) {
function refresh_fragments() {
console.log('fragments refreshed!');
$( document.body ).trigger( 'wc_fragments_refreshed' );
}
refresh_fragments();
setInterval(refresh_fragments, 5000);
});
})(jQuery);

Try the below code. instead of using the wc_fragments_refreshed trigger, you can trigger the update cart button.
Cart refresh.
(function( $ ) {
'use strict';
jQuery( document ).ready(function($) {
function refresh_fragments() {
console.log('fragments refreshed!');
jQuery( "[name='update_cart']" ).removeAttr( 'disabled' );
jQuery( "[name='update_cart']" ).trigger( 'click' );
}
setInterval(refresh_fragments, 5000);
});
})(jQuery);
UPDATE as per OP request.
Checkout Refresh.
Use update_checkout trigger.
(function( $ ) {
'use strict';
jQuery( document ).ready(function($) {
function refresh_fragments() {
$( document.body ).trigger( 'update_checkout' );
}
setInterval(refresh_fragments, 5000);
});
})(jQuery);

Related

Moving Coupon error code to bottom of woocommerce checkout page [duplicate]

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.

Elementor! How to close a popup after a few seconds at the touch of a button I make

How to close a popup after a few seconds at the click of a spacial button ?
I have written it in the comments, by I will answer as well.
Elementor Pro has JS functions for the popups. So you can call it like this
elementorProFrontend.modules.popup.closePopup( { id: yourPopupIdHere } );
All together :
jQuery( document ).ready( function( $ ) {
$( document ).on( 'click', '.close-popup', function( event ) {
setTimeout(function() {
elementorProFrontend.modules.popup.closePopup( {id: yourPopupIdHere}, event )} );
}, 4000);
});
} );
Might have gotten som syntax wrong, but it should give you an idea
One possibility is to time delay close see:
jQuery( document ).ready( function( $ ) {
setTimeout(
function(){
document.querySelector('.dialog-close-button').click();
}, 4000);
});
Possible repost of Close Elementor Popup with JavaScript

jQuery on checkout page for change of shipping method - hide show div 50% works

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);
}
} );

Woocommerce disable script opening terms inline

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.

Linking to specific ID on another Wordpress page?

I have a header.php, that appears in every single page on my blog, with a navbar that looks like this:
<nav>
<ul>
<li>Logistics</li>
<li>Contact</li>
</ul>
</nav>
But when I click the anchor tag linking to #contact, which is located in page with id 5, as you can see by the php code, nothing happens. I tried using a slash (/#contact) but I keep getting the same behavior. Isn't this the correct way of linking to a specific id on another page?
EDIT: I also have some smooth scrolling code (below) which I think may be related to my issue.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Thanks!
You have a javascript error.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Here is the problem. On the home page you have a div with id #contato. On the other pages it is not there.
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
Your hash var's value is "#contato", but when js tries to get it's offset you recieve an error saying that it's impossible to read property top of 'undefined'. So, you can try to remove that part of the script from the other pages and only keep it on home. This should work like a charm. If you have any question, please ask.
LE: I'd recommend this method for smooth scroll (I didn't tested it for your case, but it always worked for me)
$(function() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
use
<?php echo get_page_link(5)."#contact"; ?>
instead of get permalink function

Resources