如何将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
相关产品推荐
相关产品推荐

