Conditionally customizing WooCommerce checkout fields

帅比萌擦擦* 提交于 2021-02-06 14:17:24

问题


I am trying to modify WooCommerce check out fields. There are two points I want to reach.

  1. Conditional fields

    I want to make conditional fields for different shipping type in shipping section. To reach this point, Javascript is used.

  2. Administrator can edit the custom fields in the order on back-end

As a result, I write the code as below.

However, I met a problem. My javascript cannot work on the front-end.

Does anybody can help me?

    //修改check out shipping field
    add_action( 'woocommerce_before_checkout_shipping_form', 'add_shipping_type' );
    function add_shipping_type( $checkout ) {
        woocommerce_form_field( 'shipping_type', array(
            'type' => 'radio',
            'class' => array( 'form-row-wide' ),
            'label' => '收件方式',
            'options' => array(
                'shipping_1'    => '全家店到店',
                'shipping_2'    => '指定地址',
                'shipping_3' => '自行取貨',
        )
     ),$checkout->get_value( 'shipping_type' ));
    }

    add_filter( 'woocommerce_shipping_fields', 'custom_name_field_2' );
    function custom_name_field_2($fields) {
        $fields['shipping_first_name'] = array(
            'label'=>"取件者 *",
            'id' => 'shipping_first_name'
        );
        $fields['shipping_last_name'] = array(
            'label'=>"手機號碼 *",
            'id' => 'shipping_last_name'
        );
        $fields['shipping_company'] = array(
            'label'=>"店名 *",
            'id' => 'shipping_company'
        );
        $fields['shipping_city'] = array(
            'label'=>"服務編號 *",
            'id' => 'shipping_city'
        );
        $fields['shipping_address_1'] = array(
            'label'=>"收件地址 *",
            'id' => 'shipping_address_1'
        );
        $fields['shipping_address_2'] = array(
            'label'=>"預計來訪時間 *",
            'id' => 'shipping_address_2'
        );
        return $fields;
    }

    add_filter( 'woocommerce_shipping_fields', 'remove_shipping_company' );
    function remove_shipping_company($fields){
        unset($fields['shipping_country']);
        unset($fields['shipping_state']);
        return $fields;
    }


    add_filter("woocommerce_shipping_fields", "shipping_container");
    function shipping_container(){
        $output = '
        <style>label.radio{display:inline-block;margin-right:1rem;}</style>
        <script>
        var $ = jQuery.noConflict();
        $(document).ready(function(){
        $("input[name=shipping_type]").on("change",function(){
            if($("#shipping_type_shipping_1").is(":checked")) {
                    $("#shipping_first_name,#shipping_last_name,#shipping_city,#shipping_company").fadeIn();
            } else {
            $("#shipping_first_name,#shipping_last_name,#shipping_city,#shipping_company").fadeOut();
            }
            if($("#shipping_type_shipping_2").is(":checked")) {
            $("#shipping_postcode,#shipping_address_1").fadeIn();
            } else {
            $("#shipping_postcode,#shipping_address_1").fadeOut();
            }
            if($("#shipping_type_shipping_3").is(":checked")) {
            $("#shipping_address_2_field_2").fadeIn();
            } else {
            $("#shipping_address_2_field_2").fadeOut();
            }
        })
        });
        </script>
        ';
        echo $output;
    }
 

回答1:


First you can merge some functions when the same hook is involved… Then for your jQuery script is better to set it like in the following code (there is also many little mistakes in your jQuery script):

// Customizing default checkout shipping fields
add_filter( 'woocommerce_shipping_fields', 'customizing_shipping_fields' );
function customizing_shipping_fields($fields){

    # 1. Remove shipping fields
    unset($fields['shipping_country']);
    unset($fields['shipping_state']);

    # 2. Customize shipping fields
    $label_fields = array(
        'first_name' => __('取件者 *'),  'last_name'  =>   __('手機號碼 *'),
        'company'    => __('店名 *'),    'city'        => __('服務編號 *'),
        'address_1'  => __('收件地址 *'), 'address_2' => __('預計來訪時間 *'),
    );
    foreach( $label_fields as $key => $value ){
        $fields['shipping_'.$key]['label'] = $value;
        $fields['shipping_'.$key]['id'] = 'shipping_'.$key;
    }

    # 3. Customize shipping fields required
    $required_fields = array( 'first_name', 'last_name', 'company', 'city', 
        'address_1', 'address_2', 'postcode');
    foreach( $required_fields as $key => $value )
        $fields['shipping_'.$key]['required'] = false;

    return $fields;
}

// Add a Custom radio field for shipping options
add_action( 'woocommerce_before_checkout_shipping_form', 'custom_shipping_radio_button', 10, 1 );
function custom_shipping_radio_button( $checkout ) {
    # 1. CSS styling
    ?>
    <style>label.radio{ display:inline-block; margin-right:1em; }</style>
    <?php

    # 2. Add a custom radio field
    woocommerce_form_field( 'shipping_type', array(
        'type' => 'radio',
        'class' => array( 'form-row-wide' ),
        'label' => __('收件方式'),
        'options' => array(
            'shipping_1' => __('全家店到店'),
            'shipping_2' => __('指定地址'),
            'shipping_3' => __('自行取貨'),
        ),
    ), $checkout->get_value( 'shipping_type' ) );

    # 3. jQuery Script
    ?>
    <script type="text/javascript">
        jQuery(function($){
            $("input[name=shipping_type]").on("change",function(){
                if($("#shipping_type_shipping_1").is(":checked")) {
                    $("#shipping_first_name,#shipping_last_name,#shipping_city,#shipping_company").fadeIn();
                } else {
                    $("#shipping_first_name,#shipping_last_name,#shipping_city,#shipping_company").fadeOut();
                }
                if($("#shipping_type_shipping_2").is(":checked")) {
                    $("#shipping_postcode,#shipping_address_1").fadeIn();
                } else {
                    $("#shipping_postcode,#shipping_address_1").fadeOut();
                }
                if($("#shipping_type_shipping_3").is(":checked")) {
                    $("#shipping_address_2_field_2").fadeIn();
                } else {
                    $("#shipping_address_2_field_2").fadeOut();
                }
            });
        });
    </script>
    <?php
}

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

Tested and works.


Now if you want to hide fields with labels, your jQuery script will be:

    <script type="text/javascript">
        jQuery(function($){
            $("input[name=shipping_type]").on("change",function(){
                if($("#shipping_type_shipping_1").is(":checked")) {
                    $("#shipping_first_name_field,#shipping_last_name_field,#shipping_city_field,#shipping_company_field").fadeIn();
                } else {
                    $("#shipping_first_name_field,#shipping_last_name_field,#shipping_city_field,#shipping_company_field").fadeOut();
                }
                if($("#shipping_type_shipping_2").is(":checked")) {
                    $("#shipping_postcode_field,#shipping_address_1_field").fadeIn();
                } else {
                    $("#shipping_postcode_field,#shipping_address_1_field").fadeOut();
                }
                if($("#shipping_type_shipping_3").is(":checked")) {
                    $("#shipping_address_2_field_2").fadeIn();
                } else {
                    $("#shipping_address_2_field_2").fadeOut();
                }
            });
        });
    </script>

Tested and works too…

But you should need to set the fields to be not required as you will face some problems when submitting data… This will oblige you to make some other changes in order to get something functional. But this will be a new question




回答2:


@LoicTheAztec Thanks you for your reply, you gave me a great help. As you mentioned, required fields are the problem. As a result, I tried to use the code as below to solve the problem. Although it solved the problem about required fields, it cause the labels of the fields cannot be shown.

add_filter( 'woocommerce_shipping_fields', 'customizing_shipping_fields_required' );
function customizing_shipping_fields_required($fields) {
    $fields['shipping_first_name'] = array(
    'required'=>false
    );
    $fields['shipping_last_name'] = array(
    'required'=>false
    );
    $fields['shipping_company'] = array(
    'required'=>false
    );
    $fields['shipping_city'] = array(
    'required'=>false
    );
    $fields['shipping_address_1'] = array(
    'required'=>false
    );
    $fields['shipping_address_2'] = array(
    'required'=>false
    );
    $fields['shipping_postcode'] = array(
    'required'=>false
    );
    return $fields;
}



回答3:


You've missed quote around "shipping_type" on this line :

$("input[name='shipping_type'").on("change",function(){

If this fix's not working : do you have error in the javascript console ?



来源:https://stackoverflow.com/questions/48144199/conditionally-customizing-woocommerce-checkout-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!