Gravity Forms跨表单动态填充下拉框及二级联动技术问询
实现Gravity Forms工单表单的联动下拉框(设备→零件)
我来帮你搞定这个工单提交的联动下拉需求,你之前的思路方向没问题,但在函数使用和钩子绑定上有几个小问题,咱们一步步调整,最终实现「选设备→动态加载对应零件」的效果:
核心思路拆解
要实现这个联动,咱们需要分两步走:
- 先给第一个下拉框(设备)填充来自指定表单的设备条目
- 通过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>'); } }); }); });
你原来代码的问题说明
- 钩子与函数名不匹配:你用
add_filter( 'gform_get_entries_args_entry_list', 'machine' ),但定义的函数是populate_posts,这会导致代码完全不执行 - 用错了函数:
gform_get_entries_args_entry_list是过滤钩子,用来修改条目列表的参数,不是直接获取条目的函数。获取指定表单条目应该用gform_get_entries() - 缺少字段判断:你的代码会遍历表单所有字段,应该只针对目标下拉框字段处理,避免影响其他字段
内容的提问来源于stack exchange,提问作者Allen AWF
相关产品推荐
相关产品推荐

