【问题标题】:Dynamically filter Wordpress posts with dropdown menu (using php and ajax)使用下拉菜单动态过滤 Wordpress 帖子(使用 php 和 ajax)
【发布时间】:2011-06-05 08:15:51
【问题描述】:

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

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

<?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。

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

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

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

我在以下网站上找到了类似的查询: 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

如果有人可以帮助我完成所需的 javascript/Ajax,我将不胜感激。

【问题讨论】:

    标签: php ajax wordpress dynamic filter


    【解决方案1】:

    近 1000 次浏览,没有一条评论。好吧,我也需要这个,并决定去做。我已经分享了下面的 JavaScript 和 Wordpress 代码,供遥远的将来的人们使用。看起来很多,但那是因为我已经定义了一些 jQuery 函数,您可以稍后使用 .extend。它所做的只是寻找带有 CSS 类 .content-filterselect 元素(下拉菜单)。

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

    // 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 values。您可以随时使用$_GET['product_filter']$_GET['post_filter'] 在模板中的任何位置访问它,具体取决于您的类型。这意味着在任何给定页面上只能存在一个,但您希望这样 - 否则 jQuery 将不知道该使用哪个。您可以扩展此代码以设置自定义 id 或稍后您喜欢的任何内容。

    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;
        }
    }
    

    现在是有趣的部分 - 将它们放在内容页面中。我们所有的工作都得到了一些甜蜜而简短的代码:

    // 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 2014-12-04
      • 2019-01-17
      • 2015-06-30
      • 2013-12-19
      • 2018-01-19
      • 2018-09-06
      相关资源
      最近更新 更多