带自定义分类的AJAX过滤器

时间:2021-02-19 作者:Mathieu Préaud

我为自定义帖子类型创建了一个循环workshop 包含两个自定义分类法的列表groupteacher 在同一页上我要做的是创建一个包含这两种分类法的Ajax过滤器。用户可以选择一种分类法或同时选择两种分类法来显示所选的帖子。

问题是,当用户选择两种分类法时,它只显示一篇文章。当他只选择了一种分类法时,结果显示;找不到帖子"E;

按钮也是一样.filter-reset. 我创建它是为了重置选择并显示所有帖子。同样的问题,结果是;找不到帖子"E;

下面是过滤器和循环的PHP代码:

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter" class="form-filter">
  <div class="container">
  <?php

  if( $terms = get_terms( \'group\', \'orderby=name&exclude=-1\' ) ) :
    echo \'<div class="filter-tax filter--group">\';
    foreach ( $terms as $term ) :
      echo \'<input class="btn-radio" type="radio" name="categoryfilter1" value="\' . $term->term_id . \'"><label>\' . $term->name . \'</label>\';
    endforeach;
    echo \'</div>\';
   endif;

   if( $terms = get_terms( \'teacher\', \'orderby=name&exclude=-1\' ) ) :
     echo \'<div class="filter-tax filter--teacher">\';
     foreach ( $terms as $term ) :
       echo \'<input class="btn-radio" type="radio" name="categoryfilter2" value="\' . $term->term_id . \'"><label>\' . $term->name . \'</label>\';
     endforeach;
     echo \'</div>\';
    endif;

  ?>

  <a href="#" class="filter-reset">View all</a>
  <input type="hidden" name="action" value="myfilter">

  </div>
</form>


<?php
$query_args = array(
    \'post_type\' => \'workshop\',
    \'posts_per_page\' => -1,
    \'orderby\' => \'date\'
);

$the_query = new WP_Query( $query_args );

if ( $the_query->have_posts() ) :
?>
<div class="wrapper-loop">
    <?php
        while ( $the_query->have_posts() ) :
            $the_query->the_post();

            get_template_part( \'template-parts/content-archive\' );

        endwhile;
    ?>
</div><!-- .wrapper-loop -->

<?php

else :

get_template_part( \'template-parts/content\', \'none\' );

endif;
?>
用于过滤帖子的AJAX函数的PHP代码:

<?php

add_action(\'wp_ajax_myfilter\', \'site_filter_function\');
add_action(\'wp_ajax_nopriv_myfilter\', \'site_filter_function\');

function site_filter_function(){
    $args = array(
        \'orderby\' => \'date\',
        \'posts_per_page\' => -1
    );

    if( isset( $_POST[\'categoryfilter1\'] ) && isset ($_POST[\'categoryfilter2\'])  ) {
        $args[\'tax_query\'] = array(

        \'relation\' => \'AND\',

            array(
                \'taxonomy\' => \'group\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter1\']
            ),
            array(
                \'taxonomy\' => \'teacher\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter2\']
            ),
        );


    } else {

    if( isset( $_POST[\'categoryfilter1\']) && !empty( $_POST[\'categoryfilter2\'] ) )
        $args[\'tax_query\'] = array(
                \'taxonomy\' => \'group\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter1\']
        );

    if( isset( $_POST[\'categoryfilter2\']) && !empty( $_POST[\'categoryfilter1\'] ) )
        $args[\'tax_query\'] =
            array(
                \'taxonomy\' => \'teacher\',
                \'field\' => \'id\',
                \'terms\' => $_POST[\'categoryfilter2\']
        );

    }

    $query = new WP_Query( $args );

    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post();
            get_template_part( \'template-parts/content-archive\' );
        endwhile;
        wp_reset_postdata();
    else :
        echo \'No posts found\';
    endif;

    die();
}

?>
JS代码AJAX:

( function($) {

    $(\'.btn-radio\').change(function(){
    var filter = $(\'#filter\');
    $.ajax({
        url:filter.attr(\'action\'),
        data:filter.serialize(),
        type:filter.attr(\'method\'),
        beforeSend:function(xhr){
            //filter.find(\'button\').text(\'Processing...\');
        },
        success:function(data){
            //filter.find(\'button\').text(\'Filter\');
            $(\'.loop-archive-workshop\').html(data);
        }
    });
    return false;
});

$(".filter-reset").click(function() {
    document.getElementById(\'filter\').reset();
    $(\'.loop-archive-workshop\').append();

    var filter = $(\'#filter\');

    $.ajax({
        url:filter.attr(\'action\'),
        type:filter.attr(\'method\'),
        data:filter.serialize(),
        success:function(data){
            $(\'.wrapper-loop\').html(data);
        }
    });
    return false;
});


} )(jQuery);
我为这个问题挣扎了好几天。任何帮助都将不胜感激!

编辑

这是日志中的内容。txt使用过滤器时:

Array
(
    [categoryfilter1] => 7
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 5
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 4
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 7
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 7
    [categoryfilter2] => 14
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 7
    [categoryfilter2] => 8
    [action] => myfilter
)


Array
(
    [categoryfilter1] => 7
    [categoryfilter2] => 16
    [action] => myfilter
)

1 个回复
最合适的回答,由SO网友:Buttered_Toast 整理而成

问题似乎出在处理ajax reguest的php函数中执行的检查中。

第一个if 条件检查,如果两者categoryfilter1categoryfilter2 属性设置为$_POST, 然后你有else.

您的代码永远不会输入其他内容,因为根据我的了解,在给定的时间内,您将始终至少设置一个categoryfilter。

我建议使用以下方法if 条件

    if ((isset($_POST[\'categoryfilter1\']) && !empty($_POST[\'categoryfilter1\'])) && (isset($_POST[\'categoryfilter2\']) && !empty($_POST[\'categoryfilter2\']))) {
        // both properties are set and have value (not empty)
    } elseif ((isset($_POST[\'categoryfilter1\']) && !empty($_POST[\'categoryfilter1\'])) && (!isset($_POST[\'categoryfilter2\']) || empty($_POST[\'categoryfilter2\']))) {
        // only categoryfilter1 is set and has value and categoryfilter2 is either not set or set but has no value
    } elseif ((!isset($_POST[\'categoryfilter1\']) || empty($_POST[\'categoryfilter1\'])) && (isset($_POST[\'categoryfilter2\']) && !empty($_POST[\'categoryfilter2\']))) {
        // only categoryfilter2 is set and has value and categoryfilter1 is either not set or set but has no value
    }
这种检查应该能处理所有可能的结果

编辑

要查看$\\u POST的内容,可以使用PHPerror_log, 我在开发中一直使用它,它有助于显示通常无法输出到屏幕上的内容。

当使用过滤器或ajax请求时,这会有所帮助,因为这是发生在后端的进程。

error_log(print_r($_POST, true), 3, __DIR__ . \'/log.txt\');
error_log("\\r\\n\\r\\n", 3, __DIR__ . \'/log.txt\');
此代码将创建一个名为log的新文件。txt,并将包含$\\u POST的内容。

如果ajax代码位于函数中。php,日志。txt文件将与函数位于同一目录中。php。

完成删除文件后,如果无法删除,请删除其中的所有内容。

查看日志后编辑

条件可以更简单查看$\\u POST的内容,请尝试以下操作

if (isset($_POST[\'categoryfilter1\']) && isset($_POST[\'categoryfilter2\'])) {
    // both are set
} elseif (isset($_POST[\'categoryfilter1\']) && !isset($_POST[\'categoryfilter2\'])) {
    // only categoryfilter1 is set
} elseif (!isset($_POST[\'categoryfilter1\']) && isset($_POST[\'categoryfilter2\'])) {
    // only categoryfilter2 is set
}
还有

刚刚注意到,对于单个tax\\u查询,您使用

$args[\'tax_query\'] = array(
    \'taxonomy\' => \'group\',
    \'field\' => \'id\',
    \'terms\' => $_POST[\'categoryfilter1\']
);
这是不正确的,应该是这样的

$args[\'tax_query\'] = array(
    array(
        \'taxonomy\' => \'group\',
        \'field\' => \'id\',
        \'terms\' => $_POST[\'categoryfilter1\']
    )
);
tax\\u查询需要一个数组,在该数组中,您需要将每个分类法作为自己的数组传递

相关推荐

Use CSS tag inside PHP code

我试图显示/隐藏两行文本,具体取决于WooCommerce 类别为空或其中包含任何产品。使用以下命令将这些行插入到文本块中Elementor 我已经分配了CSS #ID 给每一个人,这样我就能控制它。现在,在我的自定义函数插件中,我想添加一个函数来控制使用css 类型规则:display:none;. 我现在的代码是:function show_outlet_msg($content){ $term = get_term( 40, \'product_cat\' ); $t