0

I am trying to pass the Woocommerce form field value through ajax to WC_Session.

Based partially on "Create a Custom Shipping Method for WooCommerce" tutorial and "Dynamic shipping fee based on custom radio buttons in Woocommerce" answer thread, here is an extract of code attempt:

if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {

function my_custom_shipping_method() {
        if ( ! class_exists( 'MY_Custome_Shipping_Method' ) ) {
            class my_custom_Shipping_Method extends WC_Shipping_Method {

        public function __construct() {
                    $this->id                 = 'my_custome_shipping_method';  
                    $this->method_title       = __( 'My Customize Shipping','my_custome_shipping_method' );  
                    $this->method_description = __( 'Custom Shipping Method for my custome shipping method', 'my_custome_shipping_method' );
.......
}
.......
//other shipping method code skipped
.......

public function calculate_shipping( $package = array() ) {
.......
$string = json_encode($result);
$decodedArray = json_decode($result,true);
$kekei = $decodedArray['msg'];
$balbal = array();
foreach($kekei as $goods=> $g_values) { 
    $balbal[$g_key['shipping_code'] ] = $g_values['shipping_name'];;              
}

$janggal = (array)$balbal;
WC()->session->set('janel_seesion', $balbal);
.......
}
}
}
}
}               

 add_action( 'woocommerce_shipping_init', 'my_custome_shipping_method' );

    function add_mycustome_shipping_method( $methods ) {
        $methods[] = 'My_Custome_Shipping_Method';
        return $methods;
    }

    add_filter( 'woocommerce_shipping_methods', 'add_mycustome_shipping_method' );


// Enabling delivery options for a specific defined shipping method
function targeted_shipping_method(){
    // HERE below define the shipping method Id that enable the custom delivery options
    //return 'local_pickup:5';
    return 'my_custome_shipping_method';
}

// Customizing Woocommerce checkout radio form field
add_action( 'woocommerce_form_field_radio', 'custom_form_field_radio', 20, 4 );
function custom_form_field_radio( $field, $key, $args, $value ) {
    if ( ! empty( $args['options'] ) && is_checkout() ) {
        $field = str_replace( '</label><input ', '</label><br><input ', $field );
        $field = str_replace( '<label ', '<label style="display:inline;margin-left:8px;" ', $field );
    }
    return $field;
}

add_action( 'woocommerce_review_order_after_shipping', 'custom_shipping_radio_button', 20);

function custom_shipping_radio_button() {

$domain = 'woocommerce';

if (  WC()->session->get( 'chosen_shipping_methods' )[0] == targeted_shipping_method() ) :


echo '<tr class="delivery-radio"><th>' . __('Delivery options', $domain) . '</th><td>';
$hariharikarl = WC()->session->get( 'janel_seesion' );
$chosen = WC()->session->get('chosen_delivery');
$chosen = empty($chosen) ? WC()->checkout->get_value('delivery') : $chosen;
$chosen = empty($chosen) ? 'regular' : $chosen;

// Add a custom checkbox field
woocommerce_form_field( 'radio_delivery', array(
    'type' => 'radio',
    'class' => array( 'form-row-wide' ),
    /*
    'options' => array(
    'regular' => __('Regular', $domain),
    'premium' => __('Premium +'.wc_price(2.00), $domain),
    'big' => __('Big +'.wc_price(3.00), $domain),
    'small' => __('Big +'.wc_price(5.00), $domain),

    */
    'options' => $hariharikari,
    'default' => $chosen,
), $chosen );

echo '</td></tr>';

endif;
}


// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_delivery_script' );
function checkout_delivery_script() {
    // Only checkout page
    if ( ! is_checkout() ) return;
    ?>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof wc_checkout_params === 'undefined')
            return false;

        $('form.checkout').on('change', 'input[name=radio_delivery]', function(e){
            e.preventDefault();
            var d = $(this).val();
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'delivery',
                    'delivery': d,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                    console.log(result); // just for testing | TO BE REMOVED
                },
                error: function(error){
                    console.log(error); // just for testing | TO BE REMOVED
                }
            });
        });
    });
    </script>
    <?php

}

// Get Ajax request and saving to WC session
add_action( 'wp_ajax_delivery', 'wc_get_delivery_ajax_data' );
add_action( 'wp_ajax_nopriv_delivery', 'wc_get_delivery_ajax_data' );
function wc_get_delivery_ajax_data() {
    if ( isset($_POST['delivery']) ){
        WC()->session->set('chosen_delivery', sanitize_key( $_POST['delivery'] ) );
        echo json_encode( $delivery ); // Return the value to jQuery
    }
    die();
}

// Add a custom dynamic delivery fee
add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1 );
function add_packaging_fee( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Only for targeted shipping method
    if (  WC()->session->get( 'chosen_shipping_methods' )[0] != targeted_shipping_method() )
        return;

    if( WC()->session->get( 'chosen_delivery' ) == 'regular' )
        $cart->add_fee( __( 'Delivery fee', 'woocommerce' ), 2.00 );

    if( WC()->session->get( 'chosen_delivery' ) == 'big' )
        $cart->add_fee( __( 'Delivery fee', 'woocommerce' ), 3.00 );



}

When I click the radio button I got null at console log and also the radio black dot is missing and did not stay at the same spot.

Also how am I gonna populate the last code above according from array that I have generated in my shipping methods foreach loop?

Any help is appreciated.

  • I've edited and minimize my code above for you to see the code from the beginning. I've tested my API code that produce the array in "public function calculate shipping" at another part of my XAMP server and it worked. – spider aladin Sep 02 '19 at 20:55
  • You are asking to many things at the same time in this question… You should not use WC_Sessions or $GLOBAL in your shipping method Class. So First you should solve everything related to you custom shipping method Class (one by one). Explaining what you are trying to do… Always use explicit readable variable names and comment your code… Your actual question is too broad. See [how to ask](https://stackoverflow.com/help/how-to-ask) – LoicTheAztec Sep 02 '19 at 21:49
  • For example in your `calculate_shipping()` function, `$kekei = $decodedArray['msg'];` will not give anything as `$decodedArray` is not defined in your custom shipping method code. So your code is not testable. Start from the beginning, building your custom shipping method correctly, step by step, explaining things (and again rename your variable names with something explicit and readable). If you don't do that, you will not get any useful answer. Actually your question is unclear, not testable and too broad. – LoicTheAztec Sep 02 '19 at 22:04
  • where to define $decodedArray in custom shipping method code. – spider aladin Sep 02 '19 at 22:34
  • the code in the ```public function calculate_shipping()``` can trigger the array all the radio button with its description on each button and it is visible but it cannot take the value as the console log trigger an error message ```null``` – spider aladin Sep 02 '19 at 22:42
  • i just wanted to make the ```$kekei``` array to be part of the ```woocommerce form field``` and make the radio button function properly – spider aladin Sep 03 '19 at 15:53
  • does this ```__(``` symbol plays an important role? – spider aladin Sep 03 '19 at 16:14

0 Answers0