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

ACF表单Post Object字段筛选:如何按选中客户显示对应项目?

实现ACF前端表单Client与Project的联动过滤

要让Task表单里的Project选择器仅显示与选中Client关联的项目,需要结合后端钩子过滤初始选项,再加前端JS实现实时联动,具体步骤如下:

1. 后端过滤Project字段的初始选项

使用ACF的acf/fields/post_object/query钩子,针对前端Task表单,根据已选中的Client过滤Project选项:

add_filter('acf/fields/post_object/query', 'filter_projects_by_selected_client', 10, 3);
function filter_projects_by_selected_client($args, $field, $post_id) {
    // 仅对前端Task编辑/新建表单生效
    if (!is_admin() && get_post_type($post_id) === 'tasks') {
        // 获取当前选中的Client(编辑现有Task时)
        $selected_client = get_field('client', $post_id);
        // 新建Task时,可通过URL参数?client_id=XXX预设选中的Client
        if (!$selected_client && isset($_GET['client_id'])) {
            $selected_client = absint($_GET['client_id']);
        }
        
        if ($selected_client) {
            // 过滤出关联该Client的Project(替换'client'为你Project中关联Client的ACF字段键名)
            $args['meta_query'] = array(
                array(
                    'key' => 'client',
                    'value' => $selected_client,
                    'compare' => '='
                )
            );
        }
    }
    return $args;
}

2. 前端JS实现实时联动

当用户切换Client下拉框时,通过AJAX动态更新Project选项:

第一步:注册并加载自定义JS

在主题functions.php中添加:

add_action('acf/input/admin_enqueue_scripts', 'enqueue_task_form_scripts');
function enqueue_task_form_scripts() {
    // 仅在前端Task表单页面加载脚本
    if (!is_admin() && get_post_type() === 'tasks') {
        wp_enqueue_script('task-form-script', get_template_directory_uri() . '/js/task-form.js', array('jquery', 'acf-input'), '1.0', true);
        // 传递AJAX所需参数
        wp_localize_script('task-form-script', 'taskFormAjax', array(
            'ajaxUrl' => admin_url('admin-ajax.php'),
            'nonce' => wp_create_nonce('task_form_nonce')
        ));
    }
}

第二步:编写联动逻辑JS

在主题目录下创建js/task-form.js,写入:

jQuery(document).ready(function($) {
    // 监听Client字段变化
    $('#acf-field-client').on('change', function() {
        const clientId = $(this).val();
        const projectField = $('#acf-field-project');
        
        // 清空现有选项
        projectField.empty();
        
        if (!clientId) {
            projectField.append('<option value="">请先选择客户</option>');
            return;
        }
        
        // AJAX请求获取关联项目
        $.ajax({
            url: taskFormAjax.ajaxUrl,
            type: 'POST',
            data: {
                action: 'get_projects_by_client',
                client_id: clientId,
                nonce: taskFormAjax.nonce
            },
            success: function(response) {
                projectField.append('<option value="">选择项目</option>');
                if (response.success) {
                    $.each(response.data, function(id, title) {
                        projectField.append(`<option value="${id}">${title}</option>`);
                    });
                } else {
                    projectField.append('<option value="">无关联项目</option>');
                }
            },
            error: function() {
                projectField.append('<option value="">加载失败</option>');
            }
        });
    });
    
    // 页面加载时,若已有选中的Client,自动触发一次更新
    const initialClientId = $('#acf-field-client').val();
    if (initialClientId) {
        $('#acf-field-client').trigger('change');
    }
});

3. 编写AJAX回调函数

在functions.php中添加处理AJAX请求的函数:

add_action('wp_ajax_get_projects_by_client', 'get_projects_by_client');
add_action('wp_ajax_nopriv_get_projects_by_client', 'get_projects_by_client'); // 允许未登录用户访问

function get_projects_by_client() {
    // 验证权限
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'task_form_nonce')) {
        wp_send_json_error('权限验证失败');
    }
    
    $client_id = absint($_POST['client_id']);
    if (!$client_id) {
        wp_send_json_error('无效的客户ID');
    }
    
    // 查询关联的Project(替换'client'为你Project中关联Client的ACF字段键名)
    $args = array(
        'post_type' => 'projects',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => 'client',
                'value' => $client_id,
                'compare' => '='
            )
        ),
        'orderby' => 'title',
        'order' => 'ASC'
    );
    
    $projects = get_posts($args);
    $project_options = [];
    
    foreach ($projects as $project) {
        $project_options[$project->ID] = $project->post_title;
    }
    
    wp_send_json_success($project_options);
}

注意事项

  • 替换代码中'client'为你Project自定义文章类型里,关联Client的ACF字段的真实键名
  • 确保自定义文章类型的slug与代码中的tasks、projects、clients一致
  • 新建Task时,可通过URL参数?client_id=XXX预设选中的Client,自动加载对应的Project

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:55:15