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

Gravity Forms跨表单动态填充下拉框及二级联动技术问询

实现Gravity Forms工单表单的联动下拉框(设备→零件)

我来帮你搞定这个工单提交的联动下拉需求,你之前的思路方向没问题,但在函数使用和钩子绑定上有几个小问题,咱们一步步调整,最终实现「选设备→动态加载对应零件」的效果:

核心思路拆解

要实现这个联动,咱们需要分两步走:

  1. 先给第一个下拉框(设备)填充来自指定表单的设备条目
  2. 通过AJAX监听设备选择的变化,动态拉取对应设备的零件条目填充第二个下拉框

第一步:填充设备下拉框

首先,咱们用gform_pre_render和gform_pre_validation钩子,确保表单在加载和验证阶段都能正确填充设备选项。这里要注意替换代码里的标识为你自己的表单/字段ID:

// 填充设备下拉框
add_filter( 'gform_pre_render', 'populate_device_dropdown' );
add_filter( 'gform_pre_validation', 'populate_device_dropdown' );
add_filter( 'gform_pre_submission_filter', 'populate_device_dropdown' );
add_filter( 'gform_admin_pre_render', 'populate_device_dropdown' );

function populate_device_dropdown( $form ) {
    // 替换为你的工单表单ID(用户提交工单的表单)
    $target_form_id = 1;
    // 替换为工单表单中设备下拉框的字段ID
    $device_field_id = 2;
    // 替换为存储设备条目的表单ID(专门收集设备信息的表单)
    $device_source_form_id = 3;

    // 只处理目标表单和目标字段
    if ( $form['id'] != $target_form_id ) {
        return $form;
    }

    foreach ( $form['fields'] as &$field ) {
        if ( $field->id == $device_field_id && $field->type == 'select' ) {
            // 配置获取设备条目的参数
            $args = array(
                'form_id' => $device_source_form_id,
                'status' => 'active', // 只获取已提交的有效条目
                'number_of_entries' => 100, // 按需调整显示数量
                'sort_column' => 'date_created',
                'sort_direction' => 'DESC'
            );

            // 获取指定表单的设备条目
            $device_entries = gform_get_entries( $device_source_form_id, $args );

            $choices = array();
            // 遍历条目生成下拉选项(替换'1'为你设备表单中存储名称的字段键)
            foreach ( $device_entries as $entry ) {
                $device_name = rgar( $entry, '1' );
                $device_id = $entry['id']; // 用条目ID作为值,方便后续关联零件
                $choices[] = array( 'text' => $device_name, 'value' => $device_id );
            }

            // 设置下拉框的占位符和选项
            $field->placeholder = '请选择设备';
            $field->choices = $choices;
        }
    }

    return $form;
}

第二步:实现设备→零件的联动(AJAX动态填充)

这一步需要后端写AJAX接口,前端监听设备下拉的变化,请求对应零件数据:

1. 后端AJAX处理代码

// 注册AJAX动作(支持登录/未登录用户访问)
add_action( 'wp_ajax_get_parts_by_device', 'get_parts_by_device' );
add_action( 'wp_ajax_nopriv_get_parts_by_device', 'get_parts_by_device' );

function get_parts_by_device() {
    // 检查是否传入设备ID参数
    if ( ! isset( $_POST['device_id'] ) ) {
        wp_send_json_error( '缺少设备ID参数' );
    }

    $device_id = sanitize_text_field( $_POST['device_id'] );
    // 替换为存储零件条目的表单ID
    $parts_source_form_id = 4;
    // 替换为零件表单中关联设备ID的字段键(比如'2'对应零件表单里的设备ID字段)
    $device_link_field_key = '2';

    // 配置参数:过滤出关联当前设备的零件
    $args = array(
        'form_id' => $parts_source_form_id,
        'status' => 'active',
        'number_of_entries' => 100,
        'field_filters' => array(
            array(
                'key' => $device_link_field_key,
                'value' => $device_id,
                'operator' => '='
            )
        )
    );

    $part_entries = gform_get_entries( $parts_source_form_id, $args );
    $choices = array( array( 'text' => '请选择零件', 'value' => '' ) );

    foreach ( $part_entries as $entry ) {
        // 替换'1'为零件表单中存储零件名称的字段键
        $part_name = rgar( $entry, '1' );
        $part_id = $entry['id'];
        $choices[] = array( 'text' => $part_name, 'value' => $part_id );
    }

    wp_send_json_success( $choices );
}

2. 前端JS代码(添加到主题functions.php或自定义插件)

// 加载前端脚本
add_action( 'wp_enqueue_scripts', 'enqueue_part_dropdown_script' );

function enqueue_part_dropdown_script() {
    // 只在工单表单页面加载脚本(替换为你的工单表单页面ID或slug)
    if ( is_page( 'submit-ticket' ) ) {
        wp_enqueue_script(
            'part-dropdown-script',
            get_stylesheet_directory_uri() . '/js/part-dropdown.js', // 替换为你的JS文件路径
            array( 'jquery' ),
            '1.0',
            true
        );

        // 传递AJAX地址到前端
        wp_localize_script( 'part-dropdown-script', 'gf_ajax', array(
            'ajax_url' => admin_url( 'admin-ajax.php' )
        ) );
    }
}

然后在主题的js/part-dropdown.js文件中添加:

jQuery(document).ready(function($) {
    // 替换为设备下拉框的ID(格式:#input_表单ID_字段ID)
    const deviceDropdown = $('#input_1_2');
    // 替换为零件下拉框的ID
    const partDropdown = $('#input_1_3');

    deviceDropdown.on('change', function() {
        const deviceId = $(this).val();

        // 未选择设备时重置零件下拉框
        if (!deviceId) {
            partDropdown.html('<option value="">请选择零件</option>');
            return;
        }

        // 发送AJAX请求获取零件
        $.ajax({
            url: gf_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'get_parts_by_device',
                device_id: deviceId
            },
            beforeSend: function() {
                partDropdown.html('<option value="">加载中...</option>');
            },
            success: function(response) {
                if (response.success) {
                    let options = '';
                    response.data.forEach(choice => {
                        options += `<option value="${choice.value}">${choice.text}</option>`;
                    });
                    partDropdown.html(options);
                } else {
                    partDropdown.html('<option value="">加载失败,请重试</option>');
                }
            },
            error: function() {
                partDropdown.html('<option value="">加载失败,请重试</option>');
            }
        });
    });
});

你原来代码的问题说明

  1. 钩子与函数名不匹配:你用add_filter( 'gform_get_entries_args_entry_list', 'machine' ),但定义的函数是populate_posts,这会导致代码完全不执行
  2. 用错了函数:gform_get_entries_args_entry_list是过滤钩子,用来修改条目列表的参数,不是直接获取条目的函数。获取指定表单条目应该用gform_get_entries()
  3. 缺少字段判断:你的代码会遍历表单所有字段,应该只针对目标下拉框字段处理,避免影响其他字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:54:36