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

WordPress酒店列表Ajax无提交多条件实时过滤开发求源码

嘿,我帮你整理了一套完整的WordPress Ajax实时过滤酒店列表的方案,完全适配你要的按价格、类型、星级筛选的需求——不用提交按钮,点选筛选条件就实时更新列表。直接上源码,你跟着一步步来就行!

WordPress酒店列表实时Ajax过滤实现方案

1. 先确认酒店自定义帖子类型(CPT)

首先假设你还没创建酒店专属的自定义帖子类型,先把这段代码加到主题的functions.php里:

// 注册酒店自定义帖子类型
function register_hotel_cpt() {
    $args = array(
        'public' => true,
        'label'  => '酒店',
        'supports' => array('title', 'editor', 'thumbnail'),
        'rewrite' => array('slug' => 'hotels'),
    );
    register_post_type('hotel', $args);
}
add_action('init', 'register_hotel_cpt');

接下来给酒店添加筛选需要的自定义字段:推荐用**Advanced Custom Fields(ACF)**插件创建以下字段:

  • 单选字段hotel_star_rating(选项:1星/2星/3星/4星/5星)
  • 多选字段hotel_type(选项:商务酒店/度假酒店/快捷酒店/民宿)
  • 数字字段hotel_price(存储每晚价格,单位元)

如果不用ACF,也可以用原生WordPress函数注册元字段,记得后续代码里把get_field()换成get_post_meta()即可。

2. 前端筛选表单+列表容器

把这段代码放到你的酒店列表模板里(比如archive-hotel.php或自定义模板template-hotels.php):

<div class="hotel-filters">
    <!-- 星级筛选(单选) -->
    <div class="filter-group">
        <h3>星级</h3>
        <div class="filter-options">
            <label><input type="radio" name="star_rating" value="" checked> 全部</label>
            <label><input type="radio" name="star_rating" value="1"> 1星</label>
            <label><input type="radio" name="star_rating" value="2"> 2星</label>
            <label><input type="radio" name="star_rating" value="3"> 3星</label>
            <label><input type="radio" name="star_rating" value="4"> 4星</label>
            <label><input type="radio" name="star_rating" value="5"> 5星</label>
        </div>
    </div>

    <!-- 酒店类型筛选(多选) -->
    <div class="filter-group">
        <h3>酒店类型</h3>
        <div class="filter-options">
            <label><input type="checkbox" name="hotel_type[]" value="商务酒店"> 商务酒店</label>
            <label><input type="checkbox" name="hotel_type[]" value="度假酒店"> 度假酒店</label>
            <label><input type="checkbox" name="hotel_type[]" value="快捷酒店"> 快捷酒店</label>
            <label><input type="checkbox" name="hotel_type[]" value="民宿"> 民宿</label>
        </div>
    </div>

    <!-- 价格范围筛选(单选) -->
    <div class="filter-group">
        <h3>价格范围</h3>
        <div class="filter-options">
            <label><input type="radio" name="price_range" value="" checked> 全部</label>
            <label><input type="radio" name="price_range" value="0-200"> 0-200元</label>
            <label><input type="radio" name="price_range" value="201-500"> 201-500元</label>
            <label><input type="radio" name="price_range" value="501-1000"> 501-1000元</label>
            <label><input type="radio" name="price_range" value="1000+"> 1000元以上</label>
        </div>
    </div>
</div>

<!-- 酒店列表容器 -->
<div id="hotel-list-container">
    <?php get_hotel_list(); // 初始加载酒店列表的函数 ?>
</div>

<!-- 加载提示(可选) -->
<div id="filter-loading" style="display:none;">加载中...</div>

3. PHP后台Ajax处理逻辑

把这段代码加到主题的functions.php里,负责处理筛选请求并返回匹配的酒店:

// 初始加载/Ajax回调时渲染酒店列表的函数
function get_hotel_list($args = array()) {
    $default_args = array(
        'post_type' => 'hotel',
        'posts_per_page' => 9,
        'post_status' => 'publish',
        'meta_query' => array('relation' => 'AND'),
    );

    // 合并筛选参数
    $query_args = wp_parse_args($args, $default_args);
    $hotel_query = new WP_Query($query_args);

    if ($hotel_query->have_posts()) {
        while ($hotel_query->have_posts()) {
            $hotel_query->the_post();
            $price = get_field('hotel_price');
            $stars = get_field('hotel_star_rating');
            $types = get_field('hotel_type');
            ?>
            <div class="hotel-item">
                <h4><?php the_title(); ?></h4>
                <?php if (has_post_thumbnail()) : ?>
                    <div class="hotel-thumbnail"><?php the_post_thumbnail('medium'); ?></div>
                <?php endif; ?>
                <div class="hotel-stars">星级:<?php echo $stars; ?>星</div>
                <div class="hotel-price">价格:¥<?php echo $price; ?>/晚</div>
                <div class="hotel-types">类型:<?php echo implode(', ', $types); ?></div>
                <p><?php the_excerpt(); ?></p>
            </div>
            <?php
        }
        wp_reset_postdata();
    } else {
        echo '<p>没有找到符合条件的酒店</p>';
    }
}

// 注册Ajax动作(支持登录/未登录用户)
add_action('wp_ajax_filter_hotels', 'filter_hotels_callback');
add_action('wp_ajax_nopriv_filter_hotels', 'filter_hotels_callback');

// Ajax回调:处理筛选参数并返回结果
function filter_hotels_callback() {
    $meta_query = array('relation' => 'AND');

    // 处理星级筛选
    if (!empty($_POST['star_rating'])) {
        $meta_query[] = array(
            'key' => 'hotel_star_rating',
            'value' => sanitize_text_field($_POST['star_rating']),
            'compare' => '=',
        );
    }

    // 处理酒店类型多选筛选
    if (!empty($_POST['hotel_type']) && is_array($_POST['hotel_type'])) {
        $type_clauses = array('relation' => 'OR');
        foreach ($_POST['hotel_type'] as $type) {
            $type_clauses[] = array(
                'key' => 'hotel_type',
                'value' => sanitize_text_field($type),
                'compare' => 'LIKE',
            );
        }
        $meta_query[] = $type_clauses;
    }

    // 处理价格范围筛选
    if (!empty($_POST['price_range'])) {
        $range = sanitize_text_field($_POST['price_range']);
        switch ($range) {
            case '0-200':
                $meta_query[] = array(
                    'key' => 'hotel_price',
                    'value' => array(0, 200),
                    'type' => 'NUMERIC',
                    'compare' => 'BETWEEN',
                );
                break;
            case '201-500':
                $meta_query[] = array(
                    'key' => 'hotel_price',
                    'value' => array(201, 500),
                    'type' => 'NUMERIC',
                    'compare' => 'BETWEEN',
                );
                break;
            case '501-1000':
                $meta_query[] = array(
                    'key' => 'hotel_price',
                    'value' => array(501, 1000),
                    'type' => 'NUMERIC',
                    'compare' => 'BETWEEN',
                );
                break;
            case '1000+':
                $meta_query[] = array(
                    'key' => 'hotel_price',
                    'value' => 1000,
                    'type' => 'NUMERIC',
                    'compare' => '>=',
                );
                break;
        }
    }

    // 输出筛选后的酒店列表
    get_hotel_list(array('meta_query' => $meta_query));
    wp_die(); // 必须终止Ajax请求
}

// 加载筛选脚本并传递Ajax URL
function enqueue_hotel_filter_scripts() {
    wp_enqueue_script('hotel-filter', get_template_directory_uri() . '/js/hotel-filter.js', array('jquery'), '1.0', true);
    wp_localize_script('hotel-filter', 'hotelFilterAjax', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
    ));
}
add_action('wp_enqueue_scripts', 'enqueue_hotel_filter_scripts');

4. JavaScript实时筛选逻辑

在主题目录下创建js/hotel-filter.js文件,写入以下代码:

jQuery(document).ready(function($) {
    // 监听所有筛选控件的变化
    $('.hotel-filters input').on('change', function() {
        // 显示加载状态
        $('#filter-loading').show();
        $('#hotel-list-container').fadeOut();

        // 收集所有筛选参数
        var formData = {
            action: 'filter_hotels',
            star_rating: $('input[name="star_rating"]:checked').val(),
            hotel_type: $('input[name="hotel_type[]"]:checked').map(function() {
                return $(this).val();
            }).get(),
            price_range: $('input[name="price_range"]:checked').val(),
        };

        // 发送Ajax请求更新列表
        $.ajax({
            url: hotelFilterAjax.ajaxurl,
            type: 'POST',
            data: formData,
            success: function(response) {
                $('#hotel-list-container').html(response).fadeIn();
                $('#filter-loading').hide();
            },
            error: function() {
                $('#hotel-list-container').html('<p>筛选失败,请稍后重试</p>').fadeIn();
                $('#filter-loading').hide();
            }
        });
    });
});

5. 基础样式优化(可选)

把这段CSS加到主题的style.css里,让筛选表单和列表更美观:

.hotel-filters {
    display: flex;
    gap: 2rem;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

.filter-group {
    background: #f8f9fa;
    padding: 1rem;
    border-radius: 8px;
    min-width: 200px;
}

.filter-group h3 {
    margin-top: 0;
    font-size: 1.2rem;
}

.filter-options label {
    display: block;
    margin-bottom: 0.5rem;
    cursor: pointer;
}

#hotel-list-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 2rem;
}

.hotel-item {
    border: 1px solid #eee;
    border-radius: 8px;
    padding: 1rem;
    transition: all 0.3s ease;
}

.hotel-item:hover {
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

#filter-loading {
    text-align: center;
    padding: 1rem;
    font-size: 1.1rem;
    color: #666;
}

注意事项

  • 如果不用ACF,记得把代码里的get_field()替换成get_post_meta(get_the_ID(), '字段名', true)
  • 可以根据你的实际需求修改筛选选项、字段名称、布局样式
  • 测试时确保Ajax请求正常,WordPress的admin-ajax.php路径已经通过wp_localize_script正确传递

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:38:43