awozzal
awozzal

Reputation: 61

Move Checkout Shipping Options in Woocommerce

I am trying the move the shipping options in my woocommerce checkout out of review-order.php and into form-checkout.php

I have taken the code

<?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?>
    <?php do_action( 'woocommerce_review_order_before_shipping' ); ?>
    <?php wc_cart_totals_shipping_html(); ?>
    <?php do_action( 'woocommerce_review_order_after_shipping' ); ?>
<?php endif; ?>

And moved it to my themes form-checkout.php the problem is that it will now not update the shipping when I enter or change the address. This has been accepted as a solution online but I think woocommerce has updated since then.

I think the problem is that the shipping options are now not updating when update_checkout Ajax is called but I am unsure how to change this.

Thank You


EDIT: I think I have an idea of how to do this. I have created a template checkout/shipping-options.php with

    <?php
defined( 'ABSPATH' ) || exit;
?>
<div class="card card-shipping mb-3 woocommerce-checkout-shipping-table">
                    <div class="card-header">
                        Select Shipping
                    </div>
                    <div class="card-body ">
                        <?php do_action( 'woocommerce_review_order_before_shipping' ); ?>
                        <?php wc_cart_totals_shipping_html(); ?>
                        <?php do_action( 'woocommerce_review_order_after_shipping' ); ?>
                    </div>
</div>  

Then in my functions.php I have added

    function woocommerce_checkout_shipping_options( $deprecated = false ) {
        wc_get_template(
            'checkout/shipping-options.php',
            array(
                'checkout' => WC()->checkout(),
            )
        );
    }
add_action( 'woocommerce_checkout_shipping_option', 'woocommerce_checkout_shipping_options', 10 );

Then added

<?php do_action( 'woocommerce_checkout_shipping_option' ); ?>

into form-checkout.php

and updated the woocommerce/includes/class-wc-ajax.php update_order_review function to include

// Get order review fragment.
ob_start();
woocommerce_order_review();
$woocommerce_order_review = ob_get_clean();

// Get checkout payment fragment.
ob_start();
woocommerce_checkout_payment();
$woocommerce_checkout_payment = ob_get_clean();

// Get checkout shipping fragment.
ob_start();
woocommerce_checkout_shipping_options();
$woocommerce_checkout_shipping_options = ob_get_clean();

// Get messages if reload checkout is not true.
$reload_checkout = isset( WC()->session->reload_checkout );
if ( ! $reload_checkout ) {
    $messages = wc_print_notices( true );
} else {
    $messages = '';
}

unset( WC()->session->refresh_totals, WC()->session->reload_checkout );

wp_send_json(
    array(
        'result'    => empty( $messages ) ? 'success' : 'failure',
        'messages'  => $messages,
        'reload'    => $reload_checkout,
        'fragments' => apply_filters(
            'woocommerce_update_order_review_fragments',
            array(
                '.woocommerce-checkout-review-order-table' => $woocommerce_order_review,
                '.woocommerce-checkout-payment' => $woocommerce_checkout_payment,
                '.woocommerce-checkout-shipping-table' => $woocommerce_checkout_shipping_options,
            )
        ),
    )
);

All I need to work out now is how to update the update_order_review ajax without editing the core files.

Upvotes: 3

Views: 4159

Answers (1)

Vegan Web Agency
Vegan Web Agency

Reputation: 91

I had the exact same problem and found a solution.

Step 1: Copy and remove the following code in review-order.php

<?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?>
    <?php do_action( 'woocommerce_review_order_before_shipping' ); ?>
    <?php wc_cart_totals_shipping_html(); ?>
    <?php do_action( 'woocommerce_review_order_after_shipping' ); ?>
<?php endif; ?>

Step 2: Insert it wherever you want in form-checkout.php and add a div around it

<?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?>
    <?php do_action( 'woocommerce_review_order_before_shipping' ); ?>
    <div class="my-custom-shipping-table">
        <?php wc_cart_totals_shipping_html(); ?>
    </div>
    <?php do_action( 'woocommerce_review_order_after_shipping' ); ?>
<?php endif; ?>

Step 3: Open functions.php of your child theme and add following code

function my_custom_shipping_table_update( $fragments ) {
    ob_start();
    ?>
    <div class="my-custom-shipping-table">
        <?php wc_cart_totals_shipping_html(); ?>
    </div>
    <?php
    $woocommerce_shipping_methods = ob_get_clean();
    $fragments['.my-custom-shipping-table'] = $woocommerce_shipping_methods;
    return $fragments;
}
add_filter( 'woocommerce_update_order_review_fragments', 'my_custom_shipping_table_update');

And that's a wrap. 😉

Found the solution here: https://www.ibenic.com/customize-woocommerce-checkout-pages/

Upvotes: 7

Related Questions