如何根据另一个 select 的值过滤 select 结果
How to filter select result based on another select's value
在我的 WordPress 主题中,我有一个名为 Segments 的自定义 post 类型,其中包含两个使用 ACF 制作的自定义字段。我想要实现的是根据第一个字段的值进行第二个字段的搜索。
第一个称为 emission,该字段的类型是将段 post 链接到排放分类法的分类法。
第二个称为剧集,字段类型是 post_object,它将片段 post 链接到剧集 post 类型。
现在,我想要的是第二个字段,用于过滤与第一个字段的所选值具有相同发射值的剧集。
我遇到的问题是,我无法在不保存段的情况下获取第一个字段的值。这是我尝试过的:
add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', array($this, 'show_episodes'), 10, 3);
/*
* Function to show episodes that are from the same program as the current segment.
*/
public function show_episodes($args, $field, $post_id){
error_log('Post Id: ' . $post_id);
error_log(json_encode(get_field_object('emission')));
error_log(json_encode(get_field('emission', $post_id)));
return $args;
}
当我为一个已经保存的段调用它时,它返回保存的发射值,这是合乎逻辑的,因为它是保存在数据库中的值。当我为一个新的段调用它时,它不起作用,因为它没有保存在数据库中的值,因此,它 returns a null
。每当我编辑已保存段的排放值时,它仍然是 returns 旧的排放值(来自数据库的值)。
我已经能够使用 Ajax 和 PHP 会话获得结果。这是我所做的:
Javascript
// The id of the emission field generated by ACF
this.emissionField = $('#acf-field_57473a3f32f6d-input');
if(this.emissionField.length){
let programId = this.emissionField.val();
// Update the program id on page load if it's not empty, otherwise hide the emission box
if(programId != ""){
this.updateEpisodeFilter(this.emissionField.val());
}else if(this.episodeBox.length) this.episodeBox.hide();
// Update the program id when the emission change
this.emissionField.on('change', function(){
// Clear the select on value change
$('#s2id_acf-field_57503ed5193d6-input').select2('val', '');
this.updateEpisodeFilter(this.emissionField.val());
}.bind(this));
}
/*
* Function to update the program id in the session.
*/
updateEpisodeFilter(programId){
let episodeBox = this.episodeBox;
$.ajax({
url: '/wp-admin/admin-ajax.php',
type: 'POST',
data:{
action: 'update_filter_episodes',
postId: $('#post_ID').val(),
programId: programId,
},
success: function(response){
if(response && episodeBox.length) episodeBox.show();
}
});
}
PHP
// Add the action hook for the Ajax
add_action('wp_ajax_update_filter_episodes', 'update_filter_episodes');
add_action('wp_ajax_admin_update_filter_episodes', 'update_filter_episodes');
因此,当我们通过 Ajax 接收到操作 filter_episodes
时,它会调用 PHP 函数 update_filter_episodes
。
/*
* Function to update the program id for the episodes filter.
*/
public function update_filter_episodes(){
$this->startSession();
if(isset($_POST['postId']) && isset($_POST['programId'])){
$_SESSION['post-' . $_POST['postId'] . '-emission-id'] = $_POST['programId'];
wp_send_json(true);
}
wp_send_json(false);
}
startSession 函数检查会话是否已经启动:
/*
* Function to start the session if it's not already started.
*/
protected function startSession(){
if(session_status() != PHP_SESSION_ACTIVE)
@session_start();
}
要更新 ACF 调用的查询,我们需要另一个钩子来调用函数 show_episodes
:
add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', 'show_episodes', 10, 3);
/*
* Function to show episodes that are from the same show as the current segment.
*/
public function show_episodes($args, $field, $post_id){
$this->startSession();
$index = 'post-' . $post_id . '-emission-id';
if(isset($_SESSION[$index]) && !empty($_SESSION[$index]))
$args['tax_query'] = array(array('taxonomy' => 'category', 'terms' => $_SESSION[$index]));
return $args;
}
不确定这是否是最简单的方法,但它对我有用。但是,如果有人有更好的解决方案,请随时告诉我!
在我的 WordPress 主题中,我有一个名为 Segments 的自定义 post 类型,其中包含两个使用 ACF 制作的自定义字段。我想要实现的是根据第一个字段的值进行第二个字段的搜索。
第一个称为 emission,该字段的类型是将段 post 链接到排放分类法的分类法。
第二个称为剧集,字段类型是 post_object,它将片段 post 链接到剧集 post 类型。
现在,我想要的是第二个字段,用于过滤与第一个字段的所选值具有相同发射值的剧集。
我遇到的问题是,我无法在不保存段的情况下获取第一个字段的值。这是我尝试过的:
add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', array($this, 'show_episodes'), 10, 3);
/*
* Function to show episodes that are from the same program as the current segment.
*/
public function show_episodes($args, $field, $post_id){
error_log('Post Id: ' . $post_id);
error_log(json_encode(get_field_object('emission')));
error_log(json_encode(get_field('emission', $post_id)));
return $args;
}
当我为一个已经保存的段调用它时,它返回保存的发射值,这是合乎逻辑的,因为它是保存在数据库中的值。当我为一个新的段调用它时,它不起作用,因为它没有保存在数据库中的值,因此,它 returns a null
。每当我编辑已保存段的排放值时,它仍然是 returns 旧的排放值(来自数据库的值)。
我已经能够使用 Ajax 和 PHP 会话获得结果。这是我所做的:
Javascript
// The id of the emission field generated by ACF
this.emissionField = $('#acf-field_57473a3f32f6d-input');
if(this.emissionField.length){
let programId = this.emissionField.val();
// Update the program id on page load if it's not empty, otherwise hide the emission box
if(programId != ""){
this.updateEpisodeFilter(this.emissionField.val());
}else if(this.episodeBox.length) this.episodeBox.hide();
// Update the program id when the emission change
this.emissionField.on('change', function(){
// Clear the select on value change
$('#s2id_acf-field_57503ed5193d6-input').select2('val', '');
this.updateEpisodeFilter(this.emissionField.val());
}.bind(this));
}
/*
* Function to update the program id in the session.
*/
updateEpisodeFilter(programId){
let episodeBox = this.episodeBox;
$.ajax({
url: '/wp-admin/admin-ajax.php',
type: 'POST',
data:{
action: 'update_filter_episodes',
postId: $('#post_ID').val(),
programId: programId,
},
success: function(response){
if(response && episodeBox.length) episodeBox.show();
}
});
}
PHP
// Add the action hook for the Ajax
add_action('wp_ajax_update_filter_episodes', 'update_filter_episodes');
add_action('wp_ajax_admin_update_filter_episodes', 'update_filter_episodes');
因此,当我们通过 Ajax 接收到操作 filter_episodes
时,它会调用 PHP 函数 update_filter_episodes
。
/*
* Function to update the program id for the episodes filter.
*/
public function update_filter_episodes(){
$this->startSession();
if(isset($_POST['postId']) && isset($_POST['programId'])){
$_SESSION['post-' . $_POST['postId'] . '-emission-id'] = $_POST['programId'];
wp_send_json(true);
}
wp_send_json(false);
}
startSession 函数检查会话是否已经启动:
/*
* Function to start the session if it's not already started.
*/
protected function startSession(){
if(session_status() != PHP_SESSION_ACTIVE)
@session_start();
}
要更新 ACF 调用的查询,我们需要另一个钩子来调用函数 show_episodes
:
add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', 'show_episodes', 10, 3);
/*
* Function to show episodes that are from the same show as the current segment.
*/
public function show_episodes($args, $field, $post_id){
$this->startSession();
$index = 'post-' . $post_id . '-emission-id';
if(isset($_SESSION[$index]) && !empty($_SESSION[$index]))
$args['tax_query'] = array(array('taxonomy' => 'category', 'terms' => $_SESSION[$index]));
return $args;
}
不确定这是否是最简单的方法,但它对我有用。但是,如果有人有更好的解决方案,请随时告诉我!