使用下拉菜单动态过滤 Wordpress 帖子(使用 php 和 ajax)

2021-12-23 00:00:00 dynamic filter php wordpress ajax

目标:我想制作一个动态页面,允许访问者从下拉菜单中选择月份和年份,并根据所选值更改页面上的内容(帖子).

Goal: I would like to make a dynamic page that allows the visitor to select a month and year from a drop-down menu and have the content (the posts) on the page change according the the values selected.

我目前正在使用以下代码来显示来自特定月份和年份的特定类别的帖子.

I'm currently using the following code to display posts from a particular category from a particular month and year.

<?php query_posts("cat=3&monthnum=12&year=2011"); ?> <?php if (have_posts()) : ?>
     <ul>
    <?php while (have_posts()) : the_post(); ?>
        <li>
           <?php the_title(); ?>
           <?php the_excerpt(); ?>
        </li>
    <?php endwhile; ?>
     </ul><?php endif; ?>

效果很好,但我想让页面动态化,以便访问者可以从下拉菜单中选择月份和年份,并根据所选值更改内容.我已经在这里发布了它如何工作的图片:fivepotato.com/images/ex1.png和 Fivepotato.com/images/ex2.png.

It works well, but I would like to make the page dynamic so that the visitor can select a month and year from a drop-down menu and have the content change according the the values selected. I've posted pictures of how it would work here: fivepotato.com/images/ex1.png and fivepotato.com/images/ex2.png.

要完成这项工作,我知道我必须将 monthnum 的值设为变量(取自下拉列表:

To make this work, I know that I will have to make the value of monthnum a variable (which is taken from the dropdown list:

<?php $monthvar = $_POST["month"]; query_posts("cat=3&monthnum=$monthvar&year=2011");?>

我对 Ajax 没有太多经验,但我认为我需要使用它来使内容重新过滤,每月从下拉菜单中选择一次.

I don't have much experience with Ajax, but I assume that I will need to use it to make the content re-filter once a month is selected from the dropdown menu.

我在以下网站上发现了类似的查询:askthecssguy.com/2009/03/checkbox_filters_with_jquery_1.html

I have found similar inquires on the following site: askthecssguy.com/2009/03/checkbox_filters_with_jquery_1.html

我发现了一个类似于我想做的工作示例:http://www.babycarers.com/search?ajax=0&searchref=37609&start=0&lat=&lon=&city=&radius=0&spec1=1&spec2=1&spec3=1&spec4=1&spec5=1&spec6=1&spec7=1&inst1=1&inst2=1&inst3=1&inst4=1&inst5=1&inst6=1&inst7=1&;minfee=any&maxfee=any&av1=1&keywords=&country=CA&sort=fee&resultsperpage=10

And I have found a working example similar to what I would like to do at: http://www.babycarers.com/search?ajax=0&searchref=37609&start=0&lat=&lon=&city=&radius=0&spec1=1&spec2=1&spec3=1&spec4=1&spec5=1&spec6=1&spec7=1&inst1=1&inst2=1&inst3=1&inst4=1&inst5=1&inst6=1&inst7=1&minfee=any&maxfee=any&av1=1&keywords=&country=CA&sort=fee&resultsperpage=10

如果有人可以帮助我解决实现此问题所需的 javascript/Ajax,我将不胜感激.

If anyone could help me out with the javascript/Ajax necessary to pull this off I would be greatly appreciative.

推荐答案

几乎 1000 次查看,没有一条评论.好吧,我也需要这个并决定制作它.我已经在下面分享了 JavaScript 和 Wordpress 代码,供未来的人们使用.它看起来很多,但那是因为我已经定义了一些 jQuery 函数,您可以稍后将其与 .extend 一起使用.它所做的只是寻找具有 CSS 类 .content-filterselect 元素(下拉列表).

Almost 1000 views and not a single comment. Well, I also needed this and decided to make it. I've shared the JavaScript and Wordpress code below for people in the distant future to use. It looks like a lot, but that's because I've defined some jQuery functions you can use later with .extend. All it's doing is looking for a select element (a dropdown) with CSS class .content-filter.

一旦找到,它就会使用下拉列表的 id 将 GET 变量设置为当前选择的值,然后重定向到相同的 URL 并添加这些 GET 变量.例如,如果下拉列表的 id 是 product_filter,并且它的值设置为 date,那么它将设置 GET 变量 product_filter=date.这很棒,因为它不关心您的 Wordpess 详细信息 - 它只关心 select 元素.

Once found, it uses the dropdown's id to set a GET variable to the value currently selected, then it redirects to this the same URL and adds these GET variables. For example, if the id of the dropdown was product_filter, and this had a value set to date, then it would set the GET variable product_filter=date. It's great because it doesn't care about your Wordpess details - all it cares about is the select element.

// A bunch of helper methods for reading GET variables etc from the URL
jQuery.extend({
    urlGetVars : function() {
        var GET = {};
        var tempGET = location.search;
        tempGET = tempGET.replace('?', '').split('&');
        for(var i in tempGET) {
            var someVar = tempGET[i].split('=');
            if (someVar.length == 2) {
                GET[someVar[0]] = someVar[1];
            }
        }
        return GET;
    },
    urlGetVar : function(name) {
        return $.urlGetVars()[name];
    },
    serializeUrlVars : function(obj) {
        var str = [];
        for(var p in obj)
         str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        return str.join("&");
    },
    currentUrl : function() {
        return window.location.href.slice(0,window.location.href.indexOf('?'));
    }
});

// Adds functionality to filter content using a dropdown
var ContentFilter = function ($) {
    $(document).ready(function() {
        // Return to a scroll position if exists
        var scroll = $.urlGetVar('scroll');
        if (typeof scroll != 'undefined') {
            $(window).scrollTop(scroll);
        }
        // Prepare the filter dropdowns
        $('.content-filter').each(function(){
            var me = $(this);
            // e.g. content-filter-product
            var id = me.attr('id');
            // Refresh with selected filter on change
            var refresh = function() {
                var GET = $.urlGetVars();
                GET[id] = me.val();
                // Save scroll position, return to this position on load
                GET['scroll'] = $(window).scrollTop();
                var newVar = $.currentUrl() + '?' + $.serializeUrlVars(GET);
                window.location = newVar;
            };
            me.change(refresh);
        });
    });
}(jQuery);

现在是 Wordpress 代码.我们真正需要的是生成具有某种 id 的 select 并将类设置为 .content-filter.此代码要求提供类似post"或product"的帖子类型,并生成 select 元素.为方便起见,它然后返回 GET 变量,如果没有设置,则默认为最新".请注意,$fields 数组设置了所有不同的orderby 值喜欢支持.根据您的类型,您始终可以使用 $_GET['product_filter']$_GET['post_filter'] 在模板中的任何位置访问它.这意味着在任何给定页面上只能存在一个,但您需要这样做 - 否则 jQuery 将不知道该使用哪个.您可以扩展此代码以设置自定义 ID 或您以后喜欢的任何内容.

Now the Wordpress code. All we really need is to generate the select with some kind of id and set the class to .content-filter. This code asks for a post type like 'post' or 'product' and makes the select element. It then returns the GET variable for convenience, and if none is set then it defaults to 'newest'. Notice that the $fields array sets all the different orderby values you'd like to support. You can always access it anywhere in the template with $_GET['product_filter'] or $_GET['post_filter'] depending on what your type is. This means that only one can exist on any given page, but you want that - otherwise jQuery won't know which to use. You can extend this code to set a custom id or anything you like later.

function ak_content_filter($post_type_id = 'post', &$filter_get_value, $echo = TRUE) {
    $dropdown = '<div class="content-filter-wrapper">';
    // The dropdown filter id for this post type
    $filter_id = $post_type_id.'_filter';
    // The actual dropdown
    $dropdown .= '<label for="'. $filter_id .'">Filter</label><select id="'. $filter_id .'" class="content-filter" name="'. $filter_id .'">';
    // The available ways of filtering, to sort you'd need to set that in the WP_Query later
    $fields = array('date' => 'Newest', 'comment_count' => 'Most Popular', 'rand' => 'Random');
    $filter_get_value = isset($_GET[$filter_id]) ? $_GET[$filter_id] : 'newest'; // default is 'newest'
    foreach ($fields as $field_value=>$field_name) {
        $dropdown .= '<option value="'. $field_value .'" '. selected($field_value, $filter_get_value, FALSE) .'>'. $field_name .'</option>';
    }
    $dropdown .= '</select></div>';
    // Print or return
    if ($echo) {
        echo $dropdown;
    } else {
        return $dropdown;
    }
}

现在是有趣的部分 - 将其放在内容页面中.我们所有的工作都会通过一些甜蜜而简短的代码得到回报:

Now the fun part - putting it together in the content page. All our work pays off with some sweet and short code:

// This will fill $product_filter with $_GET['product_filter'] or 'newest' if it doesn't exist
ak_content_filter('product', $product_filter);
$args = array('post_type' => 'product', 'orderby' => $product_filter);
// This is just an example, you can use get_pages or whatever supports orderby
$loop = new WP_Query( $args );

// OR, to avoid printing:
$dropdown = ak_content_filter('product', $product_filter, FALSE);
// ... some code ...
echo $dropdown;

我使用了自定义帖子类型产品",但如果您使用的是帖子",只需将其替换即可.如果他们还没有的话,有人可能应该把它变成一个插件:P

I used the custom post type 'product', but if you're using 'post' just replace that. Someone should probably make this into a plugin if they haven't already :P

相关文章