Woocommerce - Enable AJAX add to cart buttons only on specific page - ajax

On my Woocommerce shop settings I have checked the option:
[✓] Redirect to the cart page after successful addition.
And that's good behaviour for 99% of my shop.
On 1 single page (custom page with custom template) I need to enable Ajax functionality though.
Is there a way to accomplish this task in functions.php?

Ok insert this code into your functions.php. You have to replace the variable $your_ajax_page_slug with the name of your page that you want the redirect to cart functionality to be disabled. Ensure that you have 'Enable AJAX add to cart buttons on archives" checked in settings.
add_filter( 'woocommerce_get_script_data', 'modify_woocommerce_get_script_data', 20, 2 );
function modify_woocommerce_get_script_data ( $params, $handle ) {
global $wp;
$page_slug = '';
$your_ajax_page_slug = 'your-page-slug';
$current_url = home_url( $wp->request );
// Break the URL by the delimiter
$url_pieces = explode('/', $current_url);
// Get the page slug
if( is_array( $url_pieces ) )
$page_slug = end( $url_pieces );
if( $handle == 'wc-add-to-cart' && $page_slug == $your_ajax_page_slug ) {
$params['cart_redirect_after_add'] = false;
}
return $params;
}

Related

Add notice with ajax when user select local pickup shipping method on WooCommerce cart and checkout pages

I'm making a plugin for an client, integrated with WooCommerce, and I need to add a notice, with wc_add_notice, when a local pickup shipping method is selected on cart and checkout pages.
I've tried adding a hook to woocommerce_shipping_method_chosen action, like this:
add_action("woocommerce_shipping_method_chosen", "local_pickup_notice", 10, 1);
function local_pickup_notice($chosen_method){
$woocommerce = WC();
$shipping_method = $woocommerce->session->get("chosen_shipping_methods")[0];
if($shipping_method == "local_pickup"){
wc_add_notice(__("Local pickup shipping", "myplugin"), "notice");
}
}
But, it didn't work. No notice is showing on cart or checkout page when a local pickup is selected (also when changing shipping method).
Can anyone help me with this?
-- EDIT 1 --
I've noticed that woocommerce_shipping_method_chosen isn't fired, so I change action hook to woocommerce_cart_calculate_fees. Now, the action is fired, but still not showing the message.
Also tried changing from wc_add_notice to wc_print_notice, without success.
-- EDIT 2 --
My mistake was on checking the $shipping_method, because I have two local_pickup options. This way, the string stored on $shipping_method is local_pickup:<option_id> instead of only local_pickup. So, changing the if statement to use strpos instead == makes it working.
The current result is:
add_action("woocommerce_cart_calculate_fees", "local_pickup_notice", 10, 1);
function local_pickup_notice($cart){
$woocommerce = WC();
$shipping_method = $woocommerce->session->get("chosen_shipping_methods")[0];
wc_clear_notices();
if(strpos($shipping_method, "local_pickup") !== false){
wc_add_notice(__("Local pickup shipping", "myplugin"), "notice");
}
}
Now, it's working, but ONLY when the cart/checkout page is loaded. The next challenge is to make this work on the AJAX call, to show the notice when user changes shipping method.
If someone knows how to add notice on WooCommerce ajax, please tell me
wc_add_notice should be used in hooks that allow you to handle your custom AJAX endpoints. Certainly not in the woocommerce_cart_calculate_fees hook, that hook is used for other purposes.
To add a notice when user select local pickup as shipping method, you can use:
// jQuery - Ajax script
function action_wp_footer() {
// Only cart & checkout pages
if ( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ) {
$js_variable = is_cart() ? 'wc_cart_params' : 'wc_checkout_params';
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery(function($) {
if ( typeof <?php echo $js_variable; ?> === 'undefined' )
return false;
// Get chosen shipping method
var c_s_m = $( 'input[name^="shipping_method"]:checked' ).val();
// Function that sen the Ajax request
function sendAjaxRequest( c_s_m ) {
$.ajax({
type: 'POST',
url: <?php echo $js_variable; ?>.ajax_url,
data: {
'action': 'chosen_shipping_method',
'chosen_shipping_method_val': c_s_m
},
success: function ( result ) {
// Remove other notices
$( '.woocommerce-info' ).remove();
// Display notices cart
$( '.woocommerce-cart-form' ).before( result );
// Display notices checkout
$( 'form.checkout' ).before( result );
// console.log(result); // Uncomment for testing
}
});
}
// On ready (DOM loaded)
sendAjaxRequest( c_s_m );
// On live "change event"
$( document.body ).on( 'change', 'input[name^="shipping_method"]', function() {
sendAjaxRequest( $( this ).val() );
});
});
</script>
<?php
}
}
add_action( 'wp_footer', 'action_wp_footer', 10, 0 );
// Php Ajax
function chosen_shipping_method_handler() {
if ( isset( $_POST['chosen_shipping_method_val'] ) ) {
$shipping_method = sanitize_key( $_POST['chosen_shipping_method_val'] );
if ( strpos( $shipping_method, 'local_pickup' ) !== false ) {
// Add notice
wc_add_notice( __( 'Local pickup shipping', 'woocommerce' ), 'notice' );
}
}
// Return printed notices to jQuery response.
wc_print_notices();
// Alway at the end (to avoid server error 500)
die();
}
add_action( 'wp_ajax_chosen_shipping_method', 'chosen_shipping_method_handler' );
add_action( 'wp_ajax_nopriv_chosen_shipping_method', 'chosen_shipping_method_handler' );

AJAX update in VAT amount in the Cart and Checkout page - Woocommerce

I have a condition for adding VAT. If condition true then i need to update the VAT value (0). And My code is working well. But it needs to reload the page to know the value of updated VAT. How can i do it without reloading the page? My code is below:
add_action( 'woocommerce_checkout_update_order_review', 'cm_checkout_based_on_amount' );
function cm_checkout_based_on_amount( $post_data ) {
WC()->customer->set_is_vat_exempt( false );
parse_str( $post_data, $output );
$minimum = 160;
$county = array('GB');
$cart_tot_order = WC()->cart->total;
if ( $cart_tot_order > $minimum && in_array( WC()->customer->get_shipping_country(), $county ) ){
WC()->customer->set_is_vat_exempt( true );
}
}
Any help will be highly appreciated. Thanks.
You can either trigger a checkout/cart update with jQuery after these details are updated, or send custom data with the order review fragments.
To update cart/checkout trigger these:
// For checkout
$(document.body).trigger('update_checkout', { update_shipping_method: false });
// For cart
$(document.body).trigger('wc_update_cart');
To send custom fragments
add_filter('woocommerce_update_order_review_fragments', 'custom_wc_fragments');
function custom_wc_fragments($fragments)
{
ob_start();
echo 'Updated content here';
$updated_content = ob_get_clean();
$selector_of_the_element_you_want_to_update = '#order_review';
$fragments[$selector_of_the_element_you_want_to_update] = $updated_content;
return $fragments;
}
Note: these codes will not work out of the box, but they are a start to how you'll approach this.

How can I use WordPress ajax to set a cookie and redirect before a page loads

I’m working on a WordPress site requirement to redirect a user when they’re in a certain country to their country specific homepage.
(I’ve had to do this via WP Ajax because full page caching prevents it working directly on live hosting environment - I was previously doing it quite simply in functions.php hooked into 'init').
This works when I call it at the start of the header template, but only after the current page content is shown. It would be great if I could hook it in to happen before the page is displayed e.g. like using hooks such as: 'wp_loaded', ‘template_redirect’ but jQuery needs to be available...
Here is my code. It needs tidying some more but appreciate any suggestions as how to make a redirect happen before page contents displayed?
function invoke_county_redirection() {
ob_start();
?>
<script type="text/javascript">
var ajax_url = "<?= admin_url( 'admin-ajax.php' ); ?>";
jQuery.post(ajax_url, {
'action': 'country_redirection',
}, function (response) {
// Set the cookie to say we're performing the redirect - this will flag it not to happen again
createCookie('redirected', 'true');
if (response != '') {
window.location.replace(response);
}
function createCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + value + expires + "; path=/";
}
</script>
<?php
echo ob_get_clean();
return;
}
function country_redirection() {
$redirect_url = '';
if ( $_COOKIE['redirected'] !== 'true' ) {
/* declare empty result url */
$result['url'] = '';
/* Call on geoip plugin to get the country from their IP address */
$userInfo = geoip_detect2_get_info_from_current_ip();
$country_code = $userInfo->country->isoCode;
/* if we've retreived the country code for the current user */
if ( $country_code ) {
/* GET THE CORRECT REDIRECT URL IF APPLICABLE TO THE USER COUNTRY */
$redirect_url = get_country_url($country_code);
}
}
echo $redirect_url;
wp_die();
}
add_action( 'wp_ajax_nopriv_country_redirection', 'country_redirection' );
add_action( 'wp_ajax_country_redirection', 'country_redirection' );
Quick update in case anyone else can be helped by this.
I hooked the hooked the function invoke_county_redirection() into the wp_head hook as follows...
add_action('wp_head', "invoke_county_redirection");
This means that jQuery would be loaded and the country detect/redirect process runs.
However, it doesn't make the request syncronous and in this particular scenario with wanting to redirect before the page loads, I have given up on this. There is a minefield of issues trying to get around full page caching trying to store a cookie and do a redirect before the page loads. I should have just insisted that caching remained off where this needs to run, so this is our conclusion. We are instead optimsing the site as best we can with GTMetrix and loader.io and we will cross the bridge of scalability as and when we need to.

Add Woocommerce Default Product Sorting

I need to change the default sorting to another sorting.
I want on my /shop/ page category and tags pages the products to show by default the last modified.When i edit a product and i change something inside the product to move on the first row.
Is there anyone who can help me with this please?
Best Regards
WooCommerce - Change default catalog sort order. Similarly do for shop page, etc by hooks.
/**
* This code should be added to functions.php of your theme
**/
add_filter('woocommerce_default_catalog_orderby', 'custom_default_catalog_orderby');
function custom_default_catalog_orderby() {
return 'post_modified'; // Can also use title and price
}
[or]
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $args ) {
$args['orderby'] = 'last_modified';
$args['order'] = 'desc';
return $args;
}
Ref: https://gist.github.com/mikejolley/1622323
Or ref : this can do it in admin panel. but need to add the hooks in functions.php as mentioend above . Manageable in woocomerce admin panel.
http://www.remicorson.com/woocommerce-sort-products-from-oldest-to-most-recent/
Try this option it worked for me fine .
This worked for me. Manageable in woocomerce admin panel. http://www.remicorson.com/woocommerce-sort-products-from-oldest-to-most-recent/ . Add the following in your current theme (functions.php) file.
// Filters
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby' );
// Apply custom args to main query
function custom_woocommerce_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'oldest_to_recent' == $orderby_value ) {
$args['orderby'] = 'post_modified';
$args['order'] = 'DESC';
}
return $args;
}
/* Create new sorting method */
function custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['oldest_to_recent'] =
__( 'Based on Last modified to be displayed recent', 'woocommerce' );
return $sortby;
}
Go to your admin panel http://localhost/wpppame/wp-admin/admin.php?page=wc-settings&tab=products&section=display and then you will see the new option added. Select it and click save. Then go to front end of localhost/wpppame/shop, you can see the changes in the page.

Access WordPress widget options on registered sidebars through AJAX

I am in need to get widget options available in sidebars of WordPress theme.
I have built following code for accessing widget options through ajax.
add_action('wp_ajax_get_sidebar_widget_info', 'get_sidebar_widget_info');
add_action('wp_ajax_nopriv_get_sidebar_widget_info', 'get_sidebar_widget_info');
function get_sidebar_widget_info(){
header('Content-Type: application/Json');
global $wp_registered_widgets;
$response = array();
$sidebars_widget_list = get_option('sidebars_widgets');
unset($sidebars_widget_list['array_version']);
foreach($sidebars_widget_list as $sidebar_id => $widget_list){
foreach($widget_list as $widget_id){
$widget_option_name = $wp_registered_widgets[$widget_id]['callback'][0]->option_name;
$widget_number = $wp_registered_widgets[$widget_id]['params'][0]['number'];
$widget_options = get_option($widget_option_name);
$response[$sidebar_id]['widgets'][$widget_id] = $widget_options[$widget_number];
}
}
echo json_encode($response);
wp_die();
}

Resources