Move some posts to end of sort order, even if there is a sort in the wp_Query already

Question

I have a site that lists properties for sale. I have a custom wp_query, with a sort dropdown I created. This dropdown reorders the posts query by date, price (low-high & high-low) and beds (low-high & high-low). Price and beds are custom fields, with numeric values only. (no currency/comma’s).

On change, AJAX reorganises the posts below the dropdown. This all works really well.

However, some properties do not have a price (instead, they show “price on request”). The problem is, if I put their price as “0”, or leave the price field empty on these properties, then they appear in the sort order with a price of 0. So when I sort the properties by price low to high – they appear first in the listing.

I somehow need to run the sort normally, but if the property price == 0, then move them to the END of the sort order, regardless of the sort selected.

Is this possible? Maybe with pre_get_posts?

Here’s my code:

<select name="sort_by" class="sort_by_dropdown">
    <option value="dateposted-desc">Sort by Newest</option>
    <option value="price-desc">Sort by Price (High to Low)</option>
    <option value="price-asc">Sort by Price (Low to High)</option>
    <option value="bedrooms-desc">Sort by Beds (Most to Least)</option>
    <option value="bedrooms-asc">Sort by Beds (Least to Most)</option>
  </select>

<ul id="main_posts" class="item-listings">
<?php 
// Build the inital Loop
$args = array(
    'posts_per_page' => 9,
    'paged' => $paged
);

query_posts( $args );

if( have_posts() ) :

    while( have_posts() ): the_post();

        get_template_part( 'template-parts/post/content', get_post_format() );

    endwhile;
endif;?>
</ul>

and the AJAX:

 // AJAX Stuff for filters

/*
 * Filter
 */
$('#filter').change(function(){

    $.ajax({
        url : prop_loadmore_params.ajaxurl,
        data : $('#filter').serialize(), 
        dataType : 'json',
        type : 'POST',
        success : function( data ){

            // reset current page to 1 when filters on
            prop_loadmore_params.current_page = 1;

            prop_loadmore_params.posts = data.posts;

            // set max page
            prop_loadmore_params.max_page = data.max_page;

            $('#main_posts').html(data.content);

            $(".price-txt").digits(); // Add the commas!

            // If not enough posts for 2nd page, hide loadmore
            if ( data.max_page < 2 ) {
                $('#prop_loadmore').hide();
            } else {
                $('#prop_loadmore').show();
            }
        }
    });

    return false;

});

add_action('wp_ajax_prop_filters', 'property_filters'); 
add_action('wp_ajax_nopriv_prop_filters', 'property_filters');

function property_filters(){

    //*
    // Sort by Args
    //*

        if( isset( $_POST['sort_by'] ) && $_POST['sort_by'] == 'price-desc' ) {
            $orderby = 'meta_value_num'; 
            $order = 'DESC';
            $meta_key = 'price';
        }

        elseif( isset( $_POST['sort_by'] ) && $_POST['sort_by'] == 'price-asc' ) {
            $orderby = 'meta_value_num'; 
            $order = 'ASC';
            $meta_key = 'price';
        }
        elseif( isset( $_POST['sort_by'] ) && $_POST['sort_by'] == 'bedrooms-desc' ) {
            $orderby = 'meta_value_num'; 
            $order = 'DESC';
            $meta_key = 'bedrooms';
        }
        elseif( isset( $_POST['sort_by'] ) && $_POST['sort_by'] == 'bedrooms-asc' ) {
            $orderby = 'meta_value_num'; 
            $order = 'ASC';
            $meta_key = 'bedrooms';
        }
        else {
            $orderby = 'date'; 
            $order = 'DESC';
            $meta_key = '';
        }

 if (!is_user_logged_in()) {
    $args = array(
        'posts_per_page' => 9, 
        'post_status' => 'publish',
        'paged' => $_POST['page'],
        'meta_key' => $meta_key,
        'orderby' => $orderby,
        'order' => $order


    );
}
else {
    $args = array(
        'posts_per_page' => 9, 
        'meta_key' => $meta_key,
        'orderby' => $orderby,
        'order' => $order,
        'post_status' => array('publish', 'private'),
        'paged' => $_POST['page']
    );
}

    query_posts( $args );

    global $wp_query;

    if( have_posts() ) :

        ob_start();

        while( have_posts() ): the_post();

            get_template_part( 'template-parts/post/content', get_post_format() );

        endwhile;

        $posts_html = ob_get_contents(); 
        ob_end_clean(); 
    else:
        $posts_html = '<p>Nothing found for your criteria.</p>';
    endif;

    echo json_encode( array(
        'posts' => json_encode( $wp_query->query_vars ),
        'max_page' => $wp_query->max_num_pages,
        'found_posts' => $wp_query->found_posts,
        'content' => $posts_html
    ) );

    die();
}

(Side note: query posts is used because of ajax pagination combined with this, but I have removed that part of the code as I’m trying to keep the request simple!) 🙂

0
, , , user2115227 2 years 2020-01-13T08:39:34-05:00 0 Answers 75 views 0

Leave an answer

Browse
Browse