Shaun
Shaun

Reputation: 811

Add a body class for specific selected shipping option in Woocommerce checkout

I'm trying to add a class to the body of the page if a visitor is within a specific shipping option when on the Woocommerce checkout page. I've done the below but it's not adding the class? Can anyone help please?

add_filter( 'body_class', 'bbloomer_wc_product_cats_css_body_class' );

function bbloomer_wc_product_cats_css_body_class( $classes, $available_gateways ){

    global $woocommerce;
    $chosen_titles = array();
    $available_methods = $woocommerce->shipping->get_packages();
    $chosen_rates = ( isset( $woocommerce->session ) ) ? $woocommerce->session->get( 'chosen_shipping_methods' ) : array();

    foreach ($available_methods as $method)
           foreach ($chosen_rates as $chosen) {
                if( isset( $method['rates'][$chosen] ) ) $chosen_titles[] = $method['rates'][ $chosen ]->label;
            }
    if( in_array( 'Delivery price on request', $chosen_titles ) ) {
    $custom_terms = get_the_terms(0, 'product_cat');
    if ($custom_terms) {
      foreach ($custom_terms as $custom_term) {
        $classes[] = 'delivery-not-available';
      }
    }       
    }
  return $classes;
}

Upvotes: 0

Views: 1026

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253999

As this is a live event on client side, it can only be done with Javascript/jQuery

As you don't provide the shipping method ID for 'Delivery price on request' shipping method, the php code will find it before passing it to the jQuery code. When 'Delivery price on request' will be the chosen method, the class 'delivery-not-available' will be appended in body existing classes on checkout page.

The code:

add_filter( 'wp_footer','custom_product_title_script' );
function custom_product_title_script(){
    if( ! is_checkout() ) return; // only on checkout

    $method_id = "''";
    // Find the Shipping Method ID for the Shipping Method label name 'Delivery price on request'
    foreach( WC()->session->get('shipping_for_package_0')['rates'] as $rate_key => $rate ){
        if( 'Delivery price on request' == $rate->label ){
            $method_id = $rate_key;
            break;
        }
    }
    ?>
        <script type="text/javascript">
            (function($){
                // variables initialization
                var a = 'input[name^="shipping_method[0]"]',
                    b = a+':checked',
                    c = 'delivery-not-available',
                    d = '<?php echo $method_id; ?>';

                if( $(b).val() == d )
                    $('body').addClass(c);
                else
                    $('body').removeClass(c);

                $( 'form.checkout' ).on( 'change', a, function() {
                    if( $(b).val() == d )
                        $('body').addClass(c);
                    else
                        $('body').removeClass(c);
                });
            })(jQuery);
        </script>
    <?php
}

Code goes in function.php file of the active child theme (or active theme).

Tested and works.

Upvotes: 2

Related Questions