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

WooCommerce单产品页:Ajax实现按数量生成树木名称字段(无刷新)

解决WooCommerce动态生成对应数量的树木名称输入框问题

需求说明

在WordPress的WooCommerce站点销售树木时,需要根据用户选择的购买数量,无刷新动态生成对应数量的树木名称输入字段,用户下单时需填写每棵树的名称。

原代码的问题

你之前尝试用AJAX传递数量值到PHP,但核心问题在于:PHP是服务器端脚本,页面加载完成后就已经执行完毕,无法在不刷新页面的情况下通过JS修改PHP变量并重新渲染输入框。直接提交到single-product.php的AJAX请求也不符合WooCommerce规范,且无法触发PHP代码重新生成字段。

正确解决方案

改用前端JavaScript动态操作DOM来添加/移除输入框,同时配合PHP处理字段的保存与验证,确保数据能正确存入订单。

完整代码实现

1. PHP部分(字段注册、验证与数据保存)

将以下代码添加到主题的functions.php文件中:

// 在添加到购物车前显示初始的树木名称输入框
add_action('woocommerce_before_add_to_cart_button', 'render_tree_name_fields');
function render_tree_name_fields() {
    // 默认显示1个输入框
    woocommerce_form_field('tree_name_1', array(
        'type'        => 'text',
        'label'       => '树木名称 1',
        'placeholder' => '请填写树木名称',
        'class'       => array('my-field-class form-row-wide tree-name-field'),
        'required'    => true,
    ), '');
}

// 验证输入字段是否完整
add_action('woocommerce_add_to_cart_validation', 'validate_tree_name_fields', 10, 3);
function validate_tree_name_fields($passed, $product_id, $quantity) {
    // 检查每个对应数量的输入框是否都已填写
    for ($i = 1; $i <= $quantity; $i++) {
        if (empty($_POST['tree_name_' . $i])) {
            wc_add_notice('请填写第 ' . $i . ' 棵树木的名称', 'error');
            $passed = false;
            break;
        }
    }
    return $passed;
}

// 将树木名称保存到订单项元数据
add_action('woocommerce_add_order_item_meta', 'save_tree_name_to_order', 10, 3);
function save_tree_name_to_order($item_id, $values, $cart_item_key) {
    $quantity = $values['quantity'];
    for ($i = 1; $i <= $quantity; $i++) {
        if (!empty($_POST['tree_name_' . $i])) {
            wc_add_order_item_meta($item_id, '树木名称 ' . $i, sanitize_text_field($_POST['tree_name_' . $i]));
        }
    }
}

2. JavaScript部分(动态生成/移除输入框)

将以下代码添加到单产品页面的自定义脚本中(可通过主题自定义JS功能,或添加到single-product.php的合适位置):

jQuery(document).ready(function($) {
    // 获取数量输入框和字段容器
    const $quantityField = $('form.cart input[name="quantity"]');
    const $fieldsContainer = $('form.cart .tree-name-field').parent();

    // 监听数量变化
    $quantityField.on('change input', function() {
        const targetQuantity = parseInt($(this).val()) || 1;
        const currentFieldsCount = $('.tree-name-field').length;

        // 当目标数量大于当前字段数时,添加新字段
        if (targetQuantity > currentFieldsCount) {
            for (let i = currentFieldsCount + 1; i <= targetQuantity; i++) {
                const newField = `
                    <p class="form-row form-row-wide my-field-class">
                        <label for="tree_name_${i}" class="">树木名称 ${i} <abbr class="required" title="必填">*</abbr></label>
                        <span class="woocommerce-input-wrapper">
                            <input type="text" class="input-text tree-name-field" name="tree_name_${i}" id="tree_name_${i}" placeholder="请填写树木名称" required>
                        </span>
                    </p>
                `;
                $fieldsContainer.append(newField);
            }
        } 
        // 当目标数量小于当前字段数时,移除多余字段
        else if (targetQuantity < currentFieldsCount) {
            $('.tree-name-field').slice(targetQuantity).parent().remove();
        }
    });
});

代码说明

  • 前端JS:监听数量输入框的变化,对比当前已有的输入框数量,动态添加或移除对应的字段,确保字段数量和选择的购买数量一致。
  • PHP验证:添加到购物车时,检查所有对应数量的输入框是否都已填写,避免空值提交。
  • 数据保存:将填写的树木名称保存为订单项的元数据,后续在订单详情、邮件中都能查看这些信息。

内容的提问来源于stack exchange,提问作者seyed ehsan ghazi marashi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 13:50:39