最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Custom Filter for Discounted Products Not Working - Page Refreshing Instead of AJAX Loading - Stack Overflow

programmeradmin0浏览0评论

I'm trying to implement a custom filter to display discounted products in my application, ordered by the highest and lowest discount, but it's not working as expected. The products are not displaying correctly, and the page is refreshing instead of using AJAX to load the content dynamically.

Here is the code I'm currently using:

function filter_products_by_discount( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['discount_filter'] ) && ! empty( $_GET['discount_filter'] ) ) {
        $discount_filter = $_GET['discount_filter'];

        if ( $discount_filter === 'highest' ) {
            add_filter( 'posts_orderby', 'orderby_discount_highest' );
        } elseif ( $discount_filter === 'lowest' ) {
            add_filter( 'posts_orderby', 'orderby_discount_lowest' );
        }
    }
}
add_action( 'pre_get_posts', 'filter_products_by_discount' );

function orderby_discount_highest( $orderby ) {
    return "wc_product_meta._sale_price DESC";
}

function orderby_discount_lowest( $orderby ) {
    return "wc_product_meta._sale_price ASC";
}

function discount_filter_shortcode() {
    ob_start();
    ?>
    <form method="get" action="">
        <select name="discount_filter" onchange="this.form.submit();">
            <option value="">Discount Filter</option>
            <option value="highest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'highest' ) ? 'selected' : ''; ?>>highest discount</option>
            <option value="lowest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'lowest' ) ? 'selected' : ''; ?>>lowest discount</option>
        </select>
    </form>
    <?php
    return ob_get_clean();
}
add_shortcode( 'discount_filter', 'discount_filter_shortcode' );

I'm trying to implement a custom filter to display discounted products in my application, ordered by the highest and lowest discount, but it's not working as expected. The products are not displaying correctly, and the page is refreshing instead of using AJAX to load the content dynamically.

Here is the code I'm currently using:

function filter_products_by_discount( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['discount_filter'] ) && ! empty( $_GET['discount_filter'] ) ) {
        $discount_filter = $_GET['discount_filter'];

        if ( $discount_filter === 'highest' ) {
            add_filter( 'posts_orderby', 'orderby_discount_highest' );
        } elseif ( $discount_filter === 'lowest' ) {
            add_filter( 'posts_orderby', 'orderby_discount_lowest' );
        }
    }
}
add_action( 'pre_get_posts', 'filter_products_by_discount' );

function orderby_discount_highest( $orderby ) {
    return "wc_product_meta._sale_price DESC";
}

function orderby_discount_lowest( $orderby ) {
    return "wc_product_meta._sale_price ASC";
}

function discount_filter_shortcode() {
    ob_start();
    ?>
    <form method="get" action="">
        <select name="discount_filter" onchange="this.form.submit();">
            <option value="">Discount Filter</option>
            <option value="highest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'highest' ) ? 'selected' : ''; ?>>highest discount</option>
            <option value="lowest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'lowest' ) ? 'selected' : ''; ?>>lowest discount</option>
        </select>
    </form>
    <?php
    return ob_get_clean();
}
add_shortcode( 'discount_filter', 'discount_filter_shortcode' );
Share Improve this question asked Feb 5 at 15:12 user22774038user22774038 811 silver badge5 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 2

Correcting the pre_get_posts Query

function filter_products_by_discount( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['discount_filter'] ) && ! empty( $_GET['discount_filter'] ) ) {
        $discount_filter = $_GET['discount_filter'];

        $query->set( 'meta_query', array(
            'relation' => 'AND',
            array(
                'key' => '_regular_price',
                'compare' => 'EXISTS'
            ),
            array(
                'key' => '_sale_price',
                'compare' => 'EXISTS'
            ),
        ));

        if ( $discount_filter === 'highest' ) {
            $query->set( 'orderby', 'meta_value_num' );
            $query->set( 'meta_key', '_sale_price' );
            $query->set( 'order', 'DESC' );
        } elseif ( $discount_filter === 'lowest' ) {
            $query->set( 'orderby', 'meta_value_num' );
            $query->set( 'meta_key', '_sale_price' );
            $query->set( 'order', 'ASC' );
        }
    }
}
add_action( 'pre_get_posts', 'filter_products_by_discount' );

Modify your form to use AJAX instead of reloading the page:

function discount_filter_shortcode() {
    ob_start();
    ?>
    <form id="discount-filter-form">
        <select name="discount_filter" id="discount_filter">
            <option value="">Discount Filter</option>
            <option value="highest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'highest' ) ? 'selected' : ''; ?>>Highest Discount</option>
            <option value="lowest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'lowest' ) ? 'selected' : ''; ?>>Lowest Discount</option>
        </select>
    </form>

    <script>
    jQuery(document).ready(function($) {
        $('#discount_filter').change(function() {
            let filterValue = $(this).val();
            $.ajax({
                url: window.location.href, 
                type: 'GET',
                data: { discount_filter: filterValue },
                success: function(response) {
                    let newContent = $(response).find('.products'); // Adjust selector as needed
                    $('.products').html(newContent.html());
                }
            });
        });
    });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode( 'discount_filter', 'discount_filter_shortcode' );

Improved pre_get_posts Function

function filter_products_by_discount( $query ) {
    if ( ! is_admin() && $query->is_main_query() && isset( $_GET['discount_filter'] ) && ! empty( $_GET['discount_filter'] ) ) {
        global $wpdb;

        $discount_filter = $_GET['discount_filter'];

        // Custom ordering based on discount percentage
        $query->set( 'meta_query', array(
            'relation' => 'AND',
            array(
                'key' => '_regular_price',
                'compare' => 'EXISTS'
            ),
            array(
                'key' => '_sale_price',
                'compare' => 'EXISTS'
            ),
        ));

        // Custom SQL order
        $orderby_sql = "( (meta_value+0 - meta_value_num+0) / meta_value+0 ) * 100";
        
        if ( $discount_filter === 'highest' ) {
            $query->set( 'orderby', $orderby_sql );
            $query->set( 'order', 'DESC' );
        } elseif ( $discount_filter === 'lowest' ) {
            $query->set( 'orderby', $orderby_sql );
            $query->set( 'order', 'ASC' );
        }
    }
}
add_action( 'pre_get_posts', 'filter_products_by_discount' );

AJAX Support for Instant Filtering (No Page Reload)

function discount_filter_shortcode() {
    ob_start();
    ?>
    <form id="discount-filter-form">
        <select name="discount_filter" id="discount_filter">
            <option value="">Sort by Discount</option>
            <option value="highest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'highest' ) ? 'selected' : ''; ?>>Highest Discount</option>
            <option value="lowest" <?php echo ( isset($_GET['discount_filter']) && $_GET['discount_filter'] == 'lowest' ) ? 'selected' : ''; ?>>Lowest Discount</option>
        </select>
    </form>

    <script>
    jQuery(document).ready(function($) {
        $('#discount_filter').change(function() {
            let filterValue = $(this).val();
            $.ajax({
                url: window.location.href,
                type: 'GET',
                data: { discount_filter: filterValue },
                success: function(response) {
                    let newContent = $(response).find('.products'); // Adjust selector as needed
                    $('.products').html(newContent.html());
                }
            });
        });
    });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode( 'discount_filter', 'discount_filter_shortcode' );
发布评论

评论列表(0)

  1. 暂无评论