在 Woocommerce 结帐中显示或隐藏点击事件的特定账单字段

Show or hide specific billing field on click event in Woocommerce checkout

我对结帐页面上完成的工作有疑问。它似乎有效,但我不知道该过程是否正确,或者是否可以以更简洁的方式进行。

我需要隐藏账单表单中的一些字段,这些字段涉及可选的发票请求。 然后在表单之后我立即用文本 "Do you need the bill?" 钩住一个钩子并用 jQuery 单击它打开一个特定的 div。我的意图是让出现在这个 div 与发票请求相关的字段中,例如增值税号等 ...

这是我所做的:我覆盖了表单-billing.php 文件并隐藏了账单字段的默认视图:

<div class="woocommerce-billing-fields__field-wrapper">
    <?php
        $fields = $checkout->get_checkout_fields( 'billing' );

        foreach ( $fields as $key => $field ) {
            if ( isset( $field['country_field'], $fields[ $field['country_field'] ] ) ) {
                $field['country'] = $checkout->get_value( $field['country_field'] );
            }


 //here i only added this from original template:

    if ($field['label'] != 'Partita Iva') {
      woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
    }

        }
    ?>
</div>

然后在functions.php我插入了下面的代码:

add_action( 'woocommerce_after_checkout_billing_form', 'fattura_elettronica_garage' );
function fattura_elettronica_garage(){ 
    ?>
    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 mt-2 mb-2">
        <div id="click_fattura" class="caffeita_need_invoice_block pt-1 pb-1 pl-2 pr-2">
            <a class="" data-toggle="collapse" aria-expanded="true">
                <h3 class="orange mt-0">HAI BISOGNO DELLA FATTURA?</h3>
            </a>
        </div>
        <div id="fattura" class="" aria-expanded="true" style="">

            <div class="woocommerce-billing-fields__field-wrapper">
            <?php
            $checkout = new WC_Checkout();
            $fields = $checkout->get_checkout_fields( 'billing' );

            foreach ( $fields as $key => $field ) {
                if ( isset( $field['country_field'], $fields[ $field['country_field'] ] ) ) {
                    $field['country'] = $checkout->get_value( $field['country_field'] );
                }
                if ($field['label'] == 'Partita Iva') {
                    woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
                }
            }
            ?>
            <?php do_action( 'woocommerce_after_checkout_billing_form', $checkout ); ?>
            </div>
        </div>
    </div>
    <?
}

div:

<div id="fattura" class="" aria-expanded="true" >

用jquery打开它。使用此代码:

jQuery( "#fattura" ).hide();
jQuery('#click_fattura').click(function()
{
  jQuery( "#fattura" ).toggle( "slow", function() {
    // Animation complete.
  });

以及使用此代码的结帐额外字段:

function add_extra_field_checkout( $fields ) {
    $fields['billing_FIELD_ID'] = array(
        'label'        => __( 'Partita Iva' ),
        'type'        => 'text',
        'class'        => array( 'form-row-wide', 'update_totals_on_change' ),
        'priority'     => 110,
        'required'     => true,
                'placeholder'     => __( 'inserisci la Partita Iva' ),
    );

    return $fields;
}
add_filter( 'woocommerce_billing_fields', 'add_extra_field_checkout' );

这是显示 2 个相同字段(不覆盖任何模板文件)的不同代码版本方法:

  • 真正的自定义账单字段(CSS如果不存在则隐藏
  • 显示的副本带有允许显示/隐藏字段的按钮标题

有一个额外的隐藏输入字段,用于 jQuery 代码、字段验证和保存字段值。

现在,如果客户的字段值存在,则显示真实的结帐字段和相应的值 (并且不显示副本,因此没有 show/hide 功能,也没有按钮标题).

当字段值保存为自定义订单元数据时,它也会保存为自定义用户元数据。

该字段也出现在“我的帐户”>“编辑地址”>“编辑帐单地址”中。

完整代码如下:

// Custom function with the arguments arrays for the field
function get_billing_partita_iva_field_args() {
    return array(
        'type'         => 'text',
        'label'        => __( 'Partita Iva' ),
        'placeholder'  => __( 'inserisci la Partita Iva' ),
        'class'        => array( 'form-row-wide', 'update_totals_on_change' ),
        'priority'     => 110,
        'required'     => false,
    );
}

// Inline styles for checkout page
add_action( 'woocommerce_before_checkout_form', 'display_inline_styles_before_checkout_form' );
function display_inline_styles_before_checkout_form() {
    // Hide both fields (only when "partita_iva" value doesn't exist)
    if( WC()->checkout->get_value( 'billing_partita_iva' ) )
        ?><style> #billing_partita_iva_field, #fattura-field { display:none; } </style><?php
}

// Add extra checkout billing field (hidden)
add_filter( 'woocommerce_billing_fields', 'add_extra_checkout_billing_field', 10, 1 );
function add_extra_checkout_billing_field( $fields ) {
    $fields['billing_partita_iva'] = get_billing_partita_iva_field_args();

    return $fields;
}

// Add extra checkout field (that show or hide with jQuery)
add_action( 'woocommerce_after_checkout_billing_form', 'fattura_elettronica_garage' );
function fattura_elettronica_garage( $checkout ){
    $value = $checkout->get_value( 'billing_partita_iva' );

    // Active only if "Billing Partita IVA" doesn't exist yet
    if( ! $value ) :

    echo '<div id="fattura-warper" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 mt-2 mb-2">
    <div id="click-fattura" class="caffeita_need_invoice_block pt-1 pb-1 pl-2 pr-2" style="cursor:pointer;">
        <h3 class="orange mt-0">'.__("HAI BISOGNO DELLA FATTURA?").'</h3>
    </div>
    <div id="fattura-field" class="" aria-expanded="true">';

    // The field replacement (that jQuery show or hide)
    woocommerce_form_field( 'partita_iva', get_billing_partita_iva_field_args(), $value );

    // Hidden field (used by jQuery, for field validation and for saving the field value)
    echo '<input type="hidden" name="iva_on" id="iva_on" value="">
    </div></div>';

    // jQuery Show / hide custom checkout field
    ?>
    <script>
    jQuery(function($){
        $('#click-fattura').click(function() {
            if( $('#iva_on').val() != 1 ) {
                $('#fattura-field').show('slow');
                $('#iva_on').val('1');
            } else {
                $('#fattura-field').hide('slow');
                $('#iva_on').val('');
            }
            console.log('iva-on: '+$('#iva_on').val());
        });
    });
    </script>
    <?php
    endif;
}

// Process custom checkout field
add_filter( 'woocommerce_checkout_process', 'check_partita_iva_checkout_field' );
function check_partita_iva_checkout_field() {
    // If "partita_iva" is visible we check that the field has a value
    if( isset($_POST['iva_on']) && $_POST['iva_on'] == 1 && isset($_POST['partita_iva']) && empty($_POST['partita_iva']) )
        wc_add_notice( __( 'Si prega di compilare il campo "Partita Iva".', 'woocommerce' ), 'error' );
}

// Save custom checkout field value
add_filter( 'woocommerce_checkout_create_order', 'save_partita_iva_checkout_field_value', 10, 2 );
function save_partita_iva_checkout_field_value( $order, $data ) {

    // If "partita_iva" is visible we save the value of "partita_iva" to "billing_partita_iva"
    if( isset($_POST['partita_iva']) && ! empty($_POST['partita_iva']) ) {
        // Add order custom meta data
        $order->update_meta_data( '_billing_partita_iva', sanitize_text_field( $_POST['partita_iva'] ) );

        // Add user custom meta data
        if( $order->get_customer_id() )
            update_user_meta( $order->get_customer_id(), 'billing_partita_iva', sanitize_text_field( $_POST['partita_iva'] ) );
    }
    // If "partita_iva" value exist for the customer
    elseif( $order->get_customer_id() && $partita_iva = get_user_meta( $order->get_customer_id(), 'billing_partita_iva', true ) ) {
        // Add order custom meta data
        $order->update_meta_data( '_billing_partita_iva', sanitize_text_field( $_POST['partita_iva'] ) );
    }
}

代码进入活动 child 主题(或活动主题)的 function.php 文件。已测试并有效。