根据 Woocommerce 中的选定值显示或隐藏注册字段

Show or hide registration fields based on selected value in Woocommerce

我正在尝试为我的站点自定义注册表单。我一直在使用本指南并成功 created/stored 我的注册表的附加字段。 Guide to customized Registration.

我在我的注册表中创建了一个 drop-down/select 字段,供用户在注册时 select 想要标准版还是教育版 account-type:

如果他们 select 教育帐户类型,我希望显示其他字段,以便我可以为他们的学校收集更多数据。有没有办法根据表单中另一个字段的当前值提供一个字段是否可见的条件逻辑?

这是我想要完成的示例:

有人可以指出正确的方向来完成条件表单字段吗?另外,我不想为此使用 third-party 插件。完全控制对此很重要。

编辑: 根据要求,这是我的函数的完整代码:

    <?php
/*
Plugin Name: Custom Account Fields
Plugin Author: Case Silva
*/

//Create Custom Fields
if(!function_exists('get_custom_fields')){
    function get_custom_fields(){
        return apply_filters('custom_fields', array(
            'verified_education_acct' => array(
                'type' => 'checkbox',
                'label' => __('Verified?'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_registration' => true,
                'hide_in_checkout' => true
            ),
            'customer_id_num' => array(
                'type' => 'text',
                'label' => __('Customer ID# '),
                'placeholder' => __('e.g. 1234567890'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => true,
                'hide_in_registration' => true
            ),
            'account_type' => array(
                'type' => 'select',
                'label' => __('What type of account will this be?'),
                'options' => array(
                    '' => __('Select an option...'),
                    1 => __('Education'),
                    2 => __('Standard')
                ),
                'required' => true,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false
            ),
            'school_name' => array(
                'type' => 'text',
                'label' => __('School Name'),
                'placeholder' => __('e.g. North Middle School'),
                'required' => true,
                'hide_in_account' => 'account_type' != 1,
                'hide_in_admin' => false,
                'hide_in_checkout' => 'account_type' != 1,
                'hide_in_registration' => 'account_type' != 1
            ),
        ));
    }
}

//Add them to User Area
if(!function_exists('print_user_frontend_fields')){
    function print_user_frontend_fields(){
        $fields = get_custom_fields();
        $user_logged_in = is_user_logged_in();

        foreach ($fields as $key => $field_args) {
            if($user_logged_in && !empty($field_args['hide_in_account'])){
                continue;
            }
            if(! $user_logged_in && ! empty($field_args['hide_in_registration'])){
                continue;
            }
            woocommerce_form_field($key, $field_args);
        }
    }
}

//Add them to Admin Area
if(!function_exists('print_user_admin_fields')){
    function print_user_admin_fields(){
        $fields = get_custom_fields();

        ?>
        <h2><?php _e('Education/School Information'); ?></h2>
        <table class = "form-table" id = "additional-information">
            <tbody>
                <?php foreach ($fields as $key => $field_args) { ?>
                    <?php
                    if(! empty($field_args['hide_in_admin'])){
                        continue;
                    }

                    $user_id = get_edit_user_id();
                    $value = st_get_userdata($user_id, $key);
                    ?>
                    <tr>
                        <th>
                            <label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
                        </th>
                        <td>
                            <?php $field_args['label'] = false; ?>
                            <?php woocommerce_form_field($key, $field_args, $value); ?>
                        </td>
                    </tr>
                <?php } ?>
            </tbody>
        </table>
        <?php
    }
}

//Save them to the database
if(!function_exists('save_acct_fields')){
    function save_acct_fields($customer_id){
        $fields = get_custom_fields();
        $sanitized_data = array();

        foreach ($fields as $key => $field_args) {
            if(! is_field_visible($field_args)){
                continue;
            }

            $sanitize = isset($field_args['sanitize']) ? $field_args['sanitize'] : 'wc_clean';
            $value = isset($_POST[$key]) ? call_user_func($sanitize, $_POST[$key]) : '';

            if(is_userdata($key)){
                $sanitized_data[$key] = $value;
                continue;
            }

            update_user_meta($customer_id, $key, $value);
        }

        if(! empty($sanitized_data)){
            $sanitized_data['ID'] = $customer_id;
            wp_update_user($sanitized_data);
        }
    }
}

//Check if field is visible on page
if(!function_exists('is_field_visible')){
    function is_field_visible($field_args){
        $visible = true;
        $action = filter_input(INPUT_POST, action);

        if(is_admin() && ! empty($field_args['hide_in_admin'])){
            $visible = false;
        } elseif((is_account_page() || $action === 'save_account_details') && is_user_logged_in() && ! empty($field_args['hide_in_account'])){
            $visible = false;
        } elseif((is_account_page() || $action === 'save_account_details') && ! is_user_logged_in() && ! empty($field_args['hide_in_registration'])){
            $visible = false;
        } elseif(is_checkout() && ! empty($field_args['hide_in_checkout'])){
            $visible = false;
        }
        return $visible;
    }
}

//Check if field is predefined
if(!function_exists('is_userdata')){
    function is_userdata($key){
        $userdata = array(
            'user_pass',
            'user_login',
            'user_nicename',
            'user_url',
            'user_email',
            'display_name',
            'nickname',
            'first_name',
            'last_name',
            'description',
            'rich_editing',
            'user_registered',
            'role',
            'jabber',
            'aim',
            'yim',
            'show_admin_bar_front'
        );
        return in_array($key, $userdata);
    }
}

//Populate form with submitted data
if(!function_exists('get_edit_user_id')){
    function get_edit_user_id(){
        return isset($_GET['user_id']) ? (int) $_GET['user_id'] : get_current_user_id();
    }
}

//Access saved data
if(!function_exists('st_get_userdata')){
    function st_get_userdata($user_id, $key){
        if(!is_userdata($key)){
            return get_user_meta($user_id, $key, true);         
        }

        $userdata = get_userdata($user_id);

        if(!$userdata || ! isset($userdata->{$key})){
            return '';
        }

        return $userdata->{$key};
    }
}

add_action('woocommerce_register_form', 'print_user_frontend_fields', 10);
add_action('woocommerce_edit_account_form', 'print_user_frontend_fields', 10);

add_action('show_user_profile', 'print_user_admin_fields', 30);
add_action('edit_user_profile', 'print_user_admin_fields', 30);

add_action('woocommerce_created_customer', 'save_acct_fields');
add_action('personal_options_update', 'save_acct_fields');
add_action('edit_user_profile_update', 'save_acct_fields');
add_action('woocommerce_save_account_details', 'save_acct_fields');
?>

显示隐藏字段的唯一方法是使用 Javascript/jQuery,因为它是客户端的事件。

所以我对您的代码做了一些小改动,添加了必要的 jQuery 来处理显示和隐藏 school_name 文本字段,具体取决于 account_type select 字段活动选择。

这是我在您的代码中更改的两个函数:

// Get custom fields
if(!function_exists('get_custom_fields')){
    function get_custom_fields(){
        return apply_filters('custom_fields', array(
            'verified_education_acct' => array(
                'type' => 'checkbox',
                'label' => __('Verified?'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_registration' => true,
                'hide_in_checkout' => true
            ),
            'customer_id_num' => array(
                'type' => 'text',
                'label' => __('Customer ID# (Acumatica)'),
                'placeholder' => __('e.g. 1234567890'),
                'required' => false,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => true,
                'hide_in_registration' => true
            ),
            'account_type' => array(
                'type' => 'select',
                'label' => __('What type of account will this be?'),
                'class' => array('form-row-wide'),
                'options' => array(
                    '' => __('Select an option...'),
                    1 => __('Education'),
                    2 => __('Standard')
                ),
                'required' => true,
                'hide_in_account' => true,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_trigger' => true, // <===  <=== Enabling Javascript 
            ),
            'school_name' => array(
                'type' => 'text',
                'label' => __('School Name'),
                'class' => array('form-row-wide off'), // <===  <===  Hidden field
                'placeholder' => __('e.g. North Middle School'),
                'required' => true,
                'hide_in_account' => false,
                'hide_in_admin' => false,
                'hide_in_checkout' => false,
                'hide_in_registration' => false,
                'js_triggered_by' => 'account_type', // <===  JS: field that trigger show/hide
                'js_show_val' => '1', // <===  <=== JS: selected field value that show this field 
            ),
        ));
    }
}

//Add them to User Area
if(!function_exists('print_user_frontend_fields')){
    function print_user_frontend_fields(){
        $fields = get_custom_fields();
        $user_logged_in = is_user_logged_in();
        $enable_js = false; // Initializing
        $data_js = []; // Initializing

        // Hiding conditional field (with "off" class)
        echo '<style>p.form-row.off{display:none;}</style>';

        foreach ($fields as $key => $field_args) {
            if($user_logged_in && !empty($field_args['hide_in_account'])){
                continue;
            }
            if(! $user_logged_in && ! empty($field_args['hide_in_registration'])){
                continue;
            }
            if( isset($field_args['js_trigger']) && $field_args['js_trigger'] ){
                $enable_js = true;
            }
            if( isset($field_args['js_triggered_by']) && $field_args['js_show_val'] ){
                $data_js[$key] = [ $field_args['js_triggered_by'] => $field_args['js_show_val'] ];
            }
            // Form fields output
            woocommerce_form_field($key, $field_args);
        }
        if( $user_logged_in || ! $enable_js ) return; // Exit

        // JQuery code
        ?>
        <script type="text/javascript">
        jQuery( function($){
            var a = <?php echo json_encode($data_js) ?>;
            $.each(a, function(b,o){
                $.each(o, function(k,v){
                    $('#'+k).on('change', function(){
                        var cf = '#'+b+'_field';
                        if ( $(this).val() == v && $(cf).hasClass('off') ) {
                            $(cf).removeClass('off');
                        } else if ( $(this).val() != v && ! $(cf).hasClass('off') ) {
                            $(cf).addClass('off');
                        }
                    });
                });
            });
        });
        </script>
        <?php
    }
}

代码进入您的活动子主题(或活动主题)的 function.php 文件。测试和工作。

1) 加载时,字段被隐藏。

2) 在 select "Education", 字段显示

3) 在 select "Standard" (或什么都没有)字段被隐藏

to handle multiple fields you will need to make some changes, as this example is for one field.