You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将WordPress WooCommerce自定义选择字段设为必填项

问题

我在WooCommerce无变体的简单产品页面添加了面料选择下拉框,但目前未选择面料时用户仍能点击“加入购物车”按钮。需要将该选择框设为必填项,实现未选择时禁用按钮,选择后启用的效果,同时防止前端绕过校验。

当前实现代码:

add_action('woocommerce_before_add_to_cart_button','wdm_add_custom_fields');
/**
 * Adds a custom field for Product
 * @return [type] [description]
 */
function wdm_add_custom_fields()
{

    global $product;

    ob_start();

    ?>
        <div class="wdm-custom-fields">
        <label for="fabric">Fabric:</label>

        <select id="id_select2_example" name="Fabric" style="width: 150px;">
                <option data-img_src="" value="">Choose a Fabric</option>

        <option data-img_src="http://localhost/shopneyah/wp-content/uploads/2022/08/19-organic-cotton-satin-fabric-1-250x250-1.webp" value="ash">Ash</option>
        
        <option data-img_src="http://localhost/shopneyah/wp-content/uploads/2022/08/superior-quality-poly-cotton-denim-blue-white-blue-plain-poly-cotton-fabric-close-up-fabric-photo.jpg" value="Light Blue">Light Blue</option>
        <option data-img_src="http://localhost/shopneyah/wp-content/uploads/2022/08/poly-cotton-fabric.jpg" value="Dark Blue">Dark Blue</option>
        <option data-img_src="http://localhost/shopneyah/wp-content/uploads/2022/08/images-2.jpg" value="light purple">Light Purple</option>
    </select>
    </div>
    
    <!-- scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.js"></script>
<script type="text/javascript">
    function custom_template(obj){
            var data = $(obj.element).data();
            var text = $(obj.element).text();
            if(data && data['img_src']){
                img_src = data['img_src'];
                template = $("<div><img src=\"" + img_src + "\" style=\"width:35%;height:200px;\"/><p style=\"font-weight: 700;font-size:14pt;text-align:left;\>" + text + "</p></div>");
                return template;
            }
        }
    var options = {
        'templateSelection': custom_template,
        'templateResult': custom_template,
    }
    $('#id_select2_example').select2(options);
    $('.select2-container--default .select2-selection--single').css({'height': '225px'});

</script>

    <?php

    $content = ob_get_contents();
    ob_end_flush();

    return $content;
}

add_filter( 'woocommerce_checkout_fields' , 'wdm_add_custom_fields' );

解决方案

1. 前端交互:禁用按钮+监听选择变化

修改脚本部分,初始化时禁用“加入购物车”按钮,监听Select2的选择事件,根据选中状态切换按钮可用性:

<script type="text/javascript">
    function custom_template(obj){
            var data = $(obj.element).data();
            var text = $(obj.element).text();
            if(data && data['img_src']){
                img_src = data['img_src'];
                template = $("<div><img src=\"" + img_src + "\" style=\"width:35%;height:200px;\"/><p style=\"font-weight: 700;font-size:14pt;text-align:left;\">" + text + "</p></div>");
                return template;
            }
        }
    
    // 初始化禁用加入购物车按钮
    $('button.single_add_to_cart_button').prop('disabled', true).addClass('disabled');
    
    var options = {
        'templateSelection': custom_template,
        'templateResult': custom_template,
    }
    $('#id_select2_example').select2(options);
    $('.select2-container--default .select2-selection--single').css({'height': '225px'});

    // 监听Select2选择事件
    $('#id_select2_example').on('select2:select', function(e) {
        var selectedValue = $(this).val();
        if(selectedValue !== ''){
            $('button.single_add_to_cart_button').prop('disabled', false).removeClass('disabled');
        } else {
            $('button.single_add_to_cart_button').prop('disabled', true).addClass('disabled');
        }
    });

    // 处理页面刷新后的初始状态
    var initialValue = $('#id_select2_example').val();
    if(initialValue !== ''){
        $('button.single_add_to_cart_button').prop('disabled', false).removeClass('disabled');
    }
</script>

2. 后端校验:防止前端绕过

前端禁用可被篡改,必须在添加到购物车的环节做后端验证,未选择则阻止操作并提示错误:

// 验证面料选择是否必填
add_filter('woocommerce_add_to_cart_validation', 'wdm_validate_fabric_field', 10, 3);
function wdm_validate_fabric_field($passed, $product_id, $quantity) {
    if(isset($_POST['Fabric']) && empty($_POST['Fabric'])){
        wc_add_notice(__('请先选择面料再加入购物车。', 'woocommerce'), 'error');
        $passed = false;
    }
    return $passed;
}

3. 修复现有代码的错误

  • 修复HTML语法错误:将<div class="wdm-custom-fields>改为<div class="wdm-custom-fields">(缺少闭合双引号)
  • 移除冲突代码:删除add_filter( 'woocommerce_checkout_fields' , 'wdm_add_custom_fields' );,该函数用于产品页面字段,不应绑定到结账字段过滤器

内容的提问来源于stack exchange,提问作者Zia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:20:35