php - 根据选择器选择显示自定义结账字段

标签 php jquery wordpress woocommerce checkout

基于此工作答案:
Custom dropdown selector showing or hiding other Checkout custom fields

在 WooCommerce 结帐页面中,我使用下面的代码创建一些额外的自定义字段并对所有结帐字段重新排序。我使用 jQuery 脚本根据选择器选择显示/隐藏一些字段。

这是我的新代码:

// Registering external jQuery/JS file
function cfields_scripts() {

/* IMPORTANT NOTE: For a child theme replace get_template_directory_uri() by get_stylesheet_directory_uri()
                   The external cfields.js file goes in a subfolder "js" of your active child theme or theme.*/

wp_enqueue_script( 'checkout_script', get_template_directory_uri().'/js/cfields.js', array('jquery'), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'cfields_scripts' );


add_filter( 'woocommerce_checkout_fields', 'custom_checkout_billing_fields' );
function custom_checkout_billing_fields( $fields ) {

// 1. Creating the additional custom billing fields

// The "status" selector
$fields['billing']['billing_status']['type'] = 'select';
$fields['billing']['billing_status']['class'] = array('form-row-wide, status-select');
$fields['billing']['billing_status']['required'] = true;
$fields['billing']['billing_status']['label'] = __('Statut Juridic', 'my_theme_slug');
$fields['billing']['billing_status']['placeholder'] = __('Alege statutul', 'my_theme_slug');
$fields['billing']['billing_status']['options'] = array(
    '1' => __( 'Persoana Fizica', '' ),
    '2' => __( 'Persoana Juridica', '' )
);

// Customizing 'billing_company' field ['required']
$fields['billing']['billing_company']['required'] = false;
$fields['billing']['billing_company']['class'] = array('form-row-wide', 'status-group2');

// The "Nr. registrul comertului" text field
$fields['billing']['billing_ser_id']['type'] = 'text';
$fields['billing']['billing_ser_id']['class'] = array('form-row-wide', 'status-group2');
$fields['billing']['billing_ser_id']['required'] = false;
$fields['billing']['billing_ser_id']['label'] = __('Nr. Reg. Comert', 'my_theme_slug');
$fields['billing']['billing_ser_id']['placeholder'] = __('Introdu numarul', 'my_theme_slug');

// The "Banca" text field
$fields['billing']['billing_bt_id']['type'] = 'text';
$fields['billing']['billing_bt_id']['class'] = array('form-row-wide', 'status-group2');
$fields['billing']['billing_bt_id']['required'] = false;
$fields['billing']['billing_bt_id']['label'] = __('Banca', 'my_theme_slug');
$fields['billing']['billing_bt_id']['placeholder'] = __('Adauga Banca', 'my_theme_slug');

// The "IBAN" text field
$fields['billing']['billing_ib_id']['type'] = 'text';
$fields['billing']['billing_ib_id']['class'] = array('form-row-wide', 'status-group2');
$fields['billing']['billing_ib_id']['required'] = false;
$fields['billing']['billing_ib_id']['label'] = __('IBAN', 'my_theme_slug');
$fields['billing']['billing_ib_id']['placeholder'] = __('Adauga IBAN-ul', 'my_theme_slug');

// The "CIF" text field
$fields['billing']['billing_cf_id']['type'] = 'text';
$fields['billing']['billing_cf_id']['class'] = array('form-row-wide', 'status-group2');
$fields['billing']['billing_cf_id']['required'] = false;
$fields['billing']['billing_cf_id']['label'] = __('Cod Fiscal', 'my_theme_slug');
$fields['billing']['billing_cf_id']['placeholder'] = __('Adauga CIF-ul', 'my_theme_slug');


// 3. Ordering the billing fields

$fields_order = array(
    'billing_first_name', 'billing_last_name', 'billing_email',
    'billing_phone',      'billing_address_1', 'billing_address_2',
    'billing_postcode',   'billing_city',      'billing_country',
    'billing_status',
    'billing_company',  'billing_ser_id',       'billing_bt_id',
    'billing_ib_id', 'billing_cf_id'
    );
foreach($fields_order as $field) $ordered_fields[$field] = $fields['billing'][$field];

$fields['billing'] = $ordered_fields;


// Returning Checkout customized billing fields

return $fields;

}


// Process the checkout
add_action('woocommerce_checkout_process',     'my_custom_checkout_field_process');
function custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['billing_ser_id'] )
    wc_add_notice( __( 'Please enter your Serial id.' , 'my_theme_slug' ), 'error' );
if ( ! $_POST['billing_bt_id'] )
    wc_add_notice( __( 'Please enter your Serial id.' , 'my_theme_slug' ), 'error' );
if ( ! $_POST['billing_ib_id'] )
    wc_add_notice( __( 'Please enter your Serial id.' , 'my_theme_slug' ), 'error' );
if ( ! $_POST['billing_cf_id'] )
    wc_add_notice( __( 'Please enter your Serial id.' , 'my_theme_slug' ), 'error' );   
}

// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta' );
function custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['billing_ser_id'] ) )
    update_post_meta( $order_id, 'billing_ser_id', sanitize_text_field( $_POST['billing_ser_id'] ) );
if ( ! empty( $_POST['billing_bt_id'] ) )
    update_post_meta( $order_id, 'billing_bt_id', sanitize_text_field( $_POST['billing_bt_id'] ) );
if ( ! empty( $_POST['billing_ib_id'] ) )
    update_post_meta( $order_id, 'billing_ib_id', sanitize_text_field( $_POST['billing_ib_id'] ) );
if ( ! empty( $_POST['billing_cf_id'] ) )
    update_post_meta( $order_id, 'billing_cf_id', sanitize_text_field( $_POST['billing_cf_id'] ) ); 
}


// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
function custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('My serial identification').':</strong> ' . get_post_meta( $order->id, 'billing_ser_id', true ) . '</p>';
echo '<p><strong>'.__('My serial identification').':</strong> ' . get_post_meta( $order->id, 'billing_bt_id', true ) . '</p>';
echo '<p><strong>'.__('My serial identification').':</strong> ' . get_post_meta( $order->id, 'billing_ib_id', true ) . '</p>';
echo '<p><strong>'.__('My serial identification').':</strong> ' . get_post_meta( $order->id, 'billing_cf_id', true ) . '</p>';
}

Javascript cfields.js 代码 (不完整外部文件):

// This file named "cfields.js" goes in a subfolder "js" of your active child theme or theme

jQuery(document).ready(function($){

    $('#billing_company_field').hide(function(){
        $(this).removeClass("validate-required");
    });
    $('#billing_ser_id_field').hide(function(){
        $(this).removeClass("validate-required");
    });
    $("#billing_number_id_field").addClass("validate-required");

    $("#billing_status").change(function(){
        if($("#billing_status option:selected").val() == "2"){
            $('#billing_company_field').show(function(){
                $(this).addClass("validate-required");
            });
            $('#billing_ser_id_field').show(function(){
                $(this).addClass("validate-required");
            });
        } else if($("#billing_status option:selected").val() == "1"){
            $('#billing_company_field').hide(function(){
                $(this).removeClass("validate-required");
            });
            $('#billing_ser_id_field').hide(function(){
                $(this).removeClass("validate-required");
            });
        }

    });

});

因为我有一些附加字段,而我现在需要的是当 billing_status 选择器打开时:

  1. Persona Fizica 选项值(个人):仅显示 billing_serial 自定义字段。
  2. Persona Juridica 选项值(公司),将出现另外 4 个字段:

    • billing_company 现有字段(首先,在 billing_serial 之前)
    • billing_registration_id 自定义字段(在这两种情况下,此字段始终显示)
    • billing_bank_id 自定义字段
    • billing_bankno_id 自定义字段
    • billing_cif_id自定义字段

我还想在Thankyou Oder 接收页面和电子邮件通知上显示此数据。

我还没有找到让它工作的方法。我怎样才能让它正常工作?

提前致谢。

最佳答案

UPDATE HERE FOR REORDERING CHECKOUT FIELDS IN WC 3+

由于您添加了其他海关字段并进行了一些更改,您将在下面找到使其正常工作所需的代码。 这正在成为一个真正的发展,不应该在这里问。我总是尽力完成我已经开始的事情,所以我回答它。

The most difficult thing here is to avoid WooCommerce alert notice on hidden required fields when selector is on Individual. For this you are obliged (with the help of jQuery) to imput a "no" value in that hidden fields.

So when the order will be submitted, you will get all the custom fields values in the order meta data (for Individual your hidden fields will have a "no" value. It's the only possible way.
But as we can process the displayed data and even update it afterwards, this is not a problem, as you will see…

这是 PHP 代码(位于 function.php 中):

 // Registering external jQuery/JS file
function cfields_scripts() {

    // IMPORTANT NOTE:
    // For a child theme replace get_template_directory_uri() by get_stylesheet_directory_uri()
    // The external cfields.js file goes in a subfolder "js" of your active child theme or theme.
    wp_enqueue_script( 'checkout_script', get_template_directory_uri().'/js/cfields.js', array('jquery'), '1.0', true );

}
add_action( 'wp_enqueue_scripts', 'cfields_scripts' );


add_filter( 'woocommerce_checkout_fields', 'ba_custom_checkout_billing_fields' );
function ba_custom_checkout_billing_fields( $fields ) {

    // 1. Creating the additional custom billing fields

    // The "status" selector
    $fields['billing']['billing_status']['type'] = 'select';
    $fields['billing']['billing_status']['class'] = array('form-row-wide, status-select');
    $fields['billing']['billing_status']['required'] = true;
    $fields['billing']['billing_status']['label'] = __('Statut Juridic', 'theme_domain');
    $fields['billing']['billing_status']['placeholder'] = __('Alege statutul', 'theme_domain');
    $fields['billing']['billing_status']['options'] = array(
        '1' => __( 'Persoana Fizica', 'theme_domain' ),
        '2' => __( 'Persoana Juridica', 'theme_domain' )
    );

    // The "Nr. registrul comertului" text field (this field is common)
    $fields['billing']['billing_ser_id']['type'] = 'text';
    $fields['billing']['billing_ser_id']['class'] = array('form-row-wide', 'status-group2');
    $fields['billing']['billing_ser_id']['required'] = true; // <== HERE has to be "true" as it always be shown and need validation
    $fields['billing']['billing_ser_id']['label'] = __('Nr. Reg. Comert', 'theme_domain');
    $fields['billing']['billing_ser_id']['placeholder'] = __('Introdu numarul', 'theme_domain');

    // The "Banca" text field
    $fields['billing']['billing_bt_id']['type'] = 'text';
    $fields['billing']['billing_bt_id']['class'] = array('form-row-wide', 'status-group2');
    $fields['billing']['billing_bt_id']['required'] = false;
    $fields['billing']['billing_bt_id']['label'] = __('Banca', 'theme_domain');
    $fields['billing']['billing_bt_id']['placeholder'] = __('Adauga Banca', 'theme_domain');

    // The "IBAN" text field
    $fields['billing']['billing_ib_id']['type'] = 'text';
    $fields['billing']['billing_ib_id']['class'] = array('form-row-wide', 'status-group2');
    $fields['billing']['billing_ib_id']['required'] = false;
    $fields['billing']['billing_ib_id']['label'] = __('IBAN', 'theme_domain');
    $fields['billing']['billing_ib_id']['placeholder'] = __('Adauga IBAN-ul', 'theme_domain');

    // The "CIF" text field
    $fields['billing']['billing_cf_id']['type'] = 'text';
    $fields['billing']['billing_cf_id']['class'] = array('form-row-wide', 'status-group2');
    $fields['billing']['billing_cf_id']['required'] = false;
    $fields['billing']['billing_cf_id']['label'] = __('Cod Fiscal', 'theme_domain');
    $fields['billing']['billing_cf_id']['placeholder'] = __('Adauga CIF-ul', 'theme_domain');


    // 2. Ordering the billing fields

    $fields_order = array(
        'billing_first_name', 'billing_last_name', 'billing_email',
        'billing_phone',      'billing_address_1', 'billing_address_2',
        'billing_postcode',   'billing_city',      'billing_country',
        'billing_status',     'billing_company',   'billing_ser_id',
        'billing_bt_id',      'billing_ib_id',     'billing_cf_id'
    );

    foreach($fields_order as $field)
        $ordered_fields[$field] = $fields['billing'][$field];

    $fields['billing'] = $ordered_fields;


    // 4. Returning Checkout customized billing fields
    return $fields;

}


// Process the checkout (Checking if required fields are not empty)
add_action('woocommerce_checkout_process', 'ba_custom_checkout_field_process');
function ba_custom_checkout_field_process() {

    if ( ! $_POST['billing_ser_id'] )
        wc_add_notice( __( '<strong>Nr. Reg. Comert</strong> is a required field.', 'theme_domain' ), 'error' );

    if ( ! $_POST['billing_bt_id'] )
        wc_add_notice( __( '<strong>Banca</strong> is a required field.', 'theme_domain' ), 'error' );

    if ( ! $_POST['billing_ib_id'] )
        wc_add_notice( __( '<strong>IBAN</strong> is a required field.', 'theme_domain' ), 'error' );

    if ( ! $_POST['billing_cf_id'] )
        wc_add_notice( __( '<strong>Cod Fiscal</strong> is a required field.', 'theme_domain' ), 'error' );
}

// Adding/Updating meta data to the order with the custom-fields values
add_action( 'woocommerce_checkout_update_order_meta', 'ba_custom_checkout_field_update_order_meta' );
function ba_custom_checkout_field_update_order_meta( $order_id ) {

    $billing_company = $_POST['billing_company'];
    $billing_ser_id  = $_POST['billing_ser_id'];
    $billing_bt_id   = $_POST['billing_bt_id'];
    $billing_ib_id   = $_POST['billing_ib_id'];
    $billing_cf_id   = $_POST['billing_cf_id'];

    // For Individual resetting billing company to "" (no value) instead of 'no'
    if ( !empty($billing_company) && 'no' == $billing_company )
        update_post_meta( $order_id, '_billing_company', '' );

    if ( !empty($billing_ser_id) )
        update_post_meta( $order_id, '_billing_ser_id', sanitize_text_field( $billing_ser_id ) );

    // Adding/updating data only for companies
    if ( !empty($billing_bt_id) && 'no' != $billing_bt_id )
        update_post_meta( $order_id, '_billing_bt_id', sanitize_text_field( $billing_bt_id ) );

    // Adding/updating data only for companies
    if ( !empty($billing_ib_id) && 'no' != $billing_ib_id )
        update_post_meta( $order_id, '_billing_ib_id', sanitize_text_field( $billing_ib_id ) );

    // Adding/updating data only for companies
    if ( !empty($billing_cf_id) && 'no' != $billing_cf_id )
        update_post_meta( $order_id, '_billing_cf_id', sanitize_text_field( $billing_cf_id ) );
}


// Display custom-field Title/values on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'ba_custom_checkout_field_display_admin_order_meta', 10, 1 );
function ba_custom_checkout_field_display_admin_order_meta( $order ){

    $output = '';
    $billing_ser_id = get_post_meta( $order->id, '_billing_ser_id', true );
    $billing_bt_id  = get_post_meta( $order->id, '_billing_bt_id',  true );
    $billing_ib_id  = get_post_meta( $order->id, '_billing_ib_id',  true );
    $billing_cf_id  = get_post_meta( $order->id, '_billing_cf_id',  true );

    if ( !empty($billing_ser_id) ){
        $output .= '<p><strong>' . __( 'Nr. Reg. Comert', 'theme_domain' ) . ':</strong> ' . $billing_ser_id . '</p>';
    }

    if ( !empty($billing_bt_id) && 'no' != $billing_bt_id ){
        $output .= '<p><strong>' . __( 'Banca', 'theme_domain' ) . ':</strong> ' . $billing_bt_id . '</p>';
    }

    if ( !empty($billing_ib_id) && 'no' != $billing_ib_id ){
        $output .= '<p><strong>' . __( 'IBAN', 'theme_domain' ) . ':</strong> ' . $billing_ib_id . '</p>';
    }

    if ( !empty($billing_cf_id) && 'no' != $billing_cf_id ){
        $output .= '<p><strong>' . __( 'Cod Fiscal', 'theme_domain' ) . ':</strong> ' . $billing_cf_id . '</p>';
    }

    echo $output;
}

To display the data on the customer order view, on Thankyou page, My account order view and on email notifications, add this 2 code snippets in your function.php file:

// Displaying data on order view in "customer details" zone
add_action('woocommerce_order_details_after_customer_details','ba_add_values_to_order_item_meta', 10, 1 );
function ba_add_values_to_order_item_meta( $order ) {

    $output = '';
    $billing_ser_id = get_post_meta( $order->id, '_billing_ser_id', true );
    $billing_bt_id  = get_post_meta( $order->id, '_billing_bt_id',  true );
    $billing_ib_id  = get_post_meta( $order->id, '_billing_ib_id',  true );
    $billing_cf_id  = get_post_meta( $order->id, '_billing_cf_id',  true );

    if ( !empty($billing_ser_id) )
        $output .= '
        <tr>
            <th>' . __( "Nr. Reg. Comert:", "woocommerce" ) . '</th>
            <td>' . $billing_ser_id . '</td>
        </tr>';

    if ( !empty($billing_bt_id) && 'no' != $billing_bt_id )
        $output .= '
        <tr>
            <th>' . __( "Banca:", "woocommerce" ) . '</th>
            <td>' . $billing_bt_id . '</td>
        </tr>';

    if ( !empty($billing_ib_id) && 'no' != $billing_ib_id )
        $output .= '
        <tr>
            <th>' . __( "IBAN:", "woocommerce" ) . '</th>
            <td>' . $billing_ib_id . '</td>
        </tr>';

    if ( !empty($billing_cf_id) && 'no' != $billing_cf_id )
        $output .= '
        <tr>
            <th>' . __( "Cod Fiscal:", "woocommerce" ) . '</th>
            <td>' . $billing_cf_id . '</td>
        </tr>';

    echo $output;
}


// Displaying data on email notifications
add_action('woocommerce_email_customer_details','ba_add_values_to_emails_notifications', 15, 4 );
function ba_add_values_to_emails_notifications( $order, $sent_to_admin, $plain_text, $email ) {

    $output = '<ul>';
    $billing_ser_id = get_post_meta( $order->id, '_billing_ser_id', true );
    $billing_bt_id  = get_post_meta( $order->id, '_billing_bt_id',  true );
    $billing_ib_id  = get_post_meta( $order->id, '_billing_ib_id',  true );
    $billing_cf_id  = get_post_meta( $order->id, '_billing_cf_id',  true );

    if ( !empty($billing_ser_id) )
        $output .= '<li><strong>' . __( "Nr. Reg. Comert:", "woocommerce" ) . '</strong> <span class="text">' . $billing_ser_id . '</span></li>';

    if ( !empty($billing_bt_id) && 'no' != $billing_bt_id )
        $output .= '<li><strong>' . __( "Banca:", "woocommerce" ) . '</strong> <span class="text">' . $billing_bt_id . '</span></li>';

    if ( !empty($billing_ib_id) && 'no' != $billing_ib_id )
        $output .= '<li><strong>' . __( "IBAN:", "woocommerce" ) . '</strong> <span class="text">' . $billing_ib_id . '</span></li>';

    if ( !empty($billing_cf_id) && 'no' != $billing_cf_id )
        $output .= '<li><strong>' . __( "Cod Fiscal:", "woocommerce" ) . '</strong> <span class="text">' . $billing_cf_id . '</span></li>';
        $output .= '</ul>';

    echo $output;
}

Javascript cfields.js 代码(外部文件):

// This file named "cfields.js" goes in a subfolder "js" of your active child theme or theme

jQuery(document).ready(function($){

    // Common Serial ID field
    if(! $("#billing_ser_id_field").hasClass("validate-required") ){
        $("#billing_ser_id_field").addClass("validate-required");
    }


    // The 4 Fields to hide at start (if not "Persoana Juridica")
    if($("#billing_status option:selected").val() == "1"){
        $('#billing_company_field').hide(function(){
            $(this).removeClass("validate-required");
            $(this).removeClass("woocommerce-validated");
            $('#billing_company').val("no");
        });
        $('#billing_bt_id_field').hide(function(){
            $(this).removeClass("validate-required");
            $(this).removeClass("woocommerce-validated");
            $('#billing_bt_id').val("no");
        });
        $('#billing_ib_id_field').hide(function(){
            $(this).removeClass("validate-required");
            $(this).removeClass("woocommerce-validated");
            $('#billing_ib_id').val("no");
        });
        $('#billing_cf_id_field').hide(function(){
            $(this).removeClass("validate-required");
            $(this).removeClass("woocommerce-validated");
            $('#billing_cf_id').val("no");
        });
     }

    // Action with the selector (Showing/hiding and adding/removing classes)
    $("#billing_status").change(function(){
        // For "Persoana Juridica"
        if($("#billing_status option:selected").val() == "2")
        {
            $('#billing_company_field').show(function(){
                $(this).addClass("validate-required");
                $('#billing_company').val("");
            });
            $('#billing_bt_id_field').show(function(){
                $(this).children('label').append( ' <abbr class="required" title="required">*</abbr>' );
                $(this).addClass("validate-required");
                $('#billing_bt_id').val("");
            });
            $('#billing_ib_id_field').show(function(){
                $(this).children('label').append( ' <abbr class="required" title="required">*</abbr>' );
                $(this).addClass("validate-required");
                $('#billing_ib_id').val("");
            });
            $('#billing_cf_id_field').show(function(){
                $(this).children('label').append( ' <abbr class="required" title="required">*</abbr>' );
                $(this).addClass("validate-required");
                $('#billing_cf_id').val("");
            });
        }
        // For "Persoana Fizica"
        else if($("#billing_status option:selected").val() == "1")
        {
            $('#billing_company_field').hide(function(){
                $(this).removeClass("validate-required");
                $(this).removeClass("woocommerce-validated");
                $('#billing_company').val("no");
            });
            $('#billing_bt_id_field').hide(function(){
                $(this).children("abbr.required").remove();
                $(this).removeClass("validate-required");
                $(this).removeClass("woocommerce-validated");
                $('#billing_bt_id').val("no");
            });
            $('#billing_ib_id_field').hide(function(){
                $(this).children("abbr.required").remove();
                $(this).removeClass("validate-required");
                $(this).removeClass("woocommerce-validated");
                $('#billing_ib_id').val("no");
            });
            $('#billing_cf_id_field').hide(function(){
                $(this).children("abbr.required").remove();
                $(this).removeClass("validate-required");
                $(this).removeClass("woocommerce-validated");
                $('#billing_cf_id').val("no");
            });
        }

    });

});

所有这些代码都经过测试并且可以工作

关于php - 根据选择器选择显示自定义结账字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41324051/

相关文章:

css - 通过样式表为 WordPress 主题中的每个配色方案应用不同的 Logo

javascript - Codeigniter - Ajax 调用时出错 (404)

jquery - 如何在jquery中动态调用url?

c# - Asp.Net MVC 无法获取 .html 文件或 .xml 文件 404 错误?

php - 移动版 Wordpress 上的 Scrollr 问题(在哪里放置 scrollr-body id 标签)

javascript - 使用 Javascript 将 HTML 页面添加到 WordPress 网站

php - 关于重复 key 更新 - 条件 WHERE VS CASE WHEN VS IF?

php - iOS - Swift 中的密码加密

php - 从 WHMCS 获取 pdf 发票?

javascript - 如何使用 ASP.NET WebForms 在 Bootstrap 中正确插入来自 jQuery、javascript 和 CSS 的引用