Lassen Sie die AJAX-Paginierung beim Aktualisieren mit (AJAX-) URL-Filterparametern funktionieren

Lesezeit: 12 Minuten

Benutzeravatar von user2115227
Benutzer2115227

Ich habe einen gut definierten AJAX-Filter in zwei Teilen, einen für eine Schaltfläche zum Laden von mehr und einen für eine Auswahl von Dropdown-Filtern. Beide laden eine Liste von Eigenschaften auf dem Front-End in AJAX neu und arbeiten gemeinsam zusammen (z. B. wenn ich Mindestpreis, Höchstpreis und Anzahl der Betten in Dropdown-Menüs auswähle, wird die Liste aktualisiert und die Schaltfläche „Mehr laden“ funktioniert wie sie sollte) .

Dieselben Filter funktionieren auch mit URL-Parametern. Wenn die URL beispielsweise lautete:

mydomain.com/?min_price=100000&max_price=5000000&beds=3&page=3

Es würde nach diesen Parametern filtern. Es zeigt sogar 3 Seiten mit Eigenschaften, wie es sollte. Dies funktioniert hervorragend, auch beim anfänglichen Laden. Allerdings funktioniert es nicht mit der Paginierung, wenn die URL direkt geladen wird. Wenn ich die obige URL direkt in den Browser eingebe und lade, sind die anfänglichen Ergebnisse korrekt, aber wenn ich auf die Schaltfläche “Mehr laden” klicke, ändert sich Seite = 3 in Seite = 4 (richtig), aber es hängt die zweite Seite mit ungefilterten Eigenschaften an , und tut dies auch weiterhin – anstatt die gefilterte Paginierung fortzusetzen.

Was mache ich falsch?

Hier ist mein Code (sorry, es ist viel!)

JS:

jQuery(function($){


 // AJAX Stuff for filters + load more button

/*
 * Load More
 */
$('#prop_loadmore').click(function(){

    $.ajax({
        url : prop_loadmore_params.ajaxurl, 
        data : {
            'action': 'loadmorebutton',
            'query': prop_loadmore_params.posts, // loop parameters passed by wp_localize_script()
            'page' : prop_loadmore_params.current_page, // Get the current page

        },
        type : 'POST',
        beforeSend : function ( xhr ) {
            $('#prop_loadmore').text( 'Loading...' ); 
            $('#prop_loadmore').addClass( 'loading' );

        },
        success : function( posts ){
            if( posts ) {
                $('#prop_loadmore').removeClass( 'loading' );
                $('#prop_loadmore').text( 'More Listings' );
                $('#main_posts').append( posts ); 
            //    $(".price-txt").digits(); // Add the commas!
                localStorage.setItem("posts", posts);
                prop_loadmore_params.current_page++; // Increase current page by 1

                var params = new URLSearchParams(location.search);
                params.set('page', prop_loadmore_params.current_page);
                window.history.replaceState({}, "", decodeURIComponent(`${location.pathname}?${params}`));


                if ( prop_loadmore_params.current_page == prop_loadmore_params.max_page ) 
                    $('#prop_loadmore').hide(); // if last page, hide loadmore

            } else {
                $('#prop_loadmore').hide(); // if no properties, hide loadmore
            }
        }
    });
    return false;
});

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

    $.ajaxSetup({cache: false});

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

        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;

            found_posts = data.found_posts 

            //First pull out the empty strings

            var formData = $('#filter').serializeArray().filter(function (i) {
                if(i.value != 'prop_filters') {
                    return i.value;
                }
            });

            //Now push formData to URL
            window.history.pushState('', 'title', '?' + $.param(formData) + '&page=" + prop_loadmore_params.current_page);

            $("#main_posts').html(data.content);
            $('.listings-count').text( found_posts + ' Real Estate Listings for Sale' );


            if (found_posts > 9) {
                $('#prop_loadmore').show();
            }
             if ( prop_loadmore_params.current_page == prop_loadmore_params.max_page ) 
                    $('#prop_loadmore').hide(); // if last page, hide loadmore




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

    return false;

});

});

Funktionen.php :

add_action( 'wp_enqueue_scripts', 'properties_script_and_styles');

function properties_script_and_styles() {
global $wp_query;

wp_register_script( 'property_scripts', get_stylesheet_directory_uri() . '/assets/js/properties.js', array('jquery') );


$the_page = $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1;

if (!empty($_GET['page'])) {
    $the_page = $_GET['page'];
}

wp_localize_script( 'property_scripts', 'prop_loadmore_params', array(
    'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', 
    'posts' => $wp_query->query_vars,
    'current_page' => $the_page,
    'max_page' => $wp_query->max_num_pages,
    'found_posts' => $wp_query->found_posts,

) );

wp_enqueue_script( 'property_scripts' );
}

add_action('wp_ajax_loadmorebutton', 'prop_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'prop_loadmore_ajax_handler');

function prop_loadmore_ajax_handler(){

$args = json_decode(  $_POST['query'] ); 
$args['paged'] = $_POST['page'] + 1; 
 if (!is_user_logged_in()) {
    $args['post_status'] = 'publish';
}
else {
    $args['post_status'] = array('publish', 'private');
}
query_posts( $args );

if( have_posts() ) :


    while( have_posts() ): the_post();

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

    endwhile;
endif;
die;
}


function prepare_property_filters(array $args): array {

/** Price Args**/

if (!empty($_REQUEST['price_min']) || !empty($_REQUEST['price_max'])) 
{
    $args['meta_query'] = ['relation'=>'AND'];
}

// If Both
if( !empty( $_REQUEST['price_min'] ) && !empty( $_REQUEST['price_max'] )) {
    $args['meta_query'][] = array(
        'key' => 'price',
        'value' => array( $_REQUEST['price_min'], 
$_REQUEST['price_max'] ),
        'type' => 'numeric',
        'compare' => 'between'
    );
} else {
    // if only min price
    if( !empty( $_REQUEST['price_min'] ) ) {
        $args['meta_query'][] = array(
            'key' => 'price',
            'value' => $_REQUEST['price_min'],
            'type' => 'numeric',
            'compare' => '>'
        );
    }
}

    // if only max price
    if( !empty( $_REQUEST['price_max'] ) ) {
        $args['meta_query'][] = array(
            'key' => 'price',
            'value' => $_REQUEST['price_max'],
            'type' => 'numeric',
            'compare' => '<'
        );
    }

//* 
// Bedrooms Arg
//*
    if( !empty( $_REQUEST['beds'] ) ) {
        $args['meta_query'][] = array(
            'key' => 'bedrooms',
            'value' => $_REQUEST['beds'],
            'type' => 'numeric',
            'compare' => '>='
        );
    }

//* 
// Property Type Arg
//*
    if( !empty( $_REQUEST['type'] ) ) {
        $args['meta_query'][] = array(
            'key' => 'property_type',
            'value' => $_REQUEST['type'],
            'compare' => 'IN'
        );
    }

return $args;
}


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

function property_filters() {
//*
// Sort by Args
//*

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

    elseif( $_REQUEST['sort_by'] === 'price-asc' ) {
        $orderby = 'meta_value_num'; 
        $order="ASC";
        $meta_key = 'price';
    }
    elseif( $_REQUEST['sort_by'] === 'bedrooms-desc' ) {
        $orderby = 'meta_value_num'; 
        $order="DESC";
        $meta_key = 'bedrooms';
    }
    elseif( $_REQUEST["sort_by"] === 'bedrooms-asc' ) {
        $orderby = 'meta_value_num'; 
        $order="ASC";
        $meta_key = 'bedrooms';
    }
    else {
        $orderby = 'date'; 
        $order="DESC";
        $meta_key = '';
    }
$args = prepare_property_filters([
    'posts_per_page' => 9, 
    'post_status' => is_user_logged_in() ? ['publish', 'private'] : ['publish'],
    'paged' => $_POST['page'],
    'meta_key' => $meta_key,
    'orderby' => $orderby,
    'order' => $order
]);
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();
}

und der HTML-Code:

<input id="filter_toggle"  type="checkbox">
<?php //We need to save the varaibles in arrays, so we can then check them against the URL and populate the dropdowns

$price_min = [
'' => 'Any Price',
'100000' => '$100,000',
'150000' => '$150,000',
'200000' => '$200,000',
'250000' => '$250,000',
//etc
];

$price_max = [
'' => 'Any Price',
'100000' => '$100,000',
'150000' => '$150,000',
'200000' => '$200,000',
'250000' => '$250,000',
//etc
];

$beds = [
'' => 'All Beds',
'1' => '1+',
'2' => '2+',
'3' => '3+',
'4' => '4+',
'5' => '5+'
];

$property_type = [
'' => 'All Property Types',
'single-family-home' => 'Single Family Home',
'condo' => 'Condo',
'land' => 'Land',
'townhouse' => 'Townhouse'
];

$sort_by = [
'newest' => 'Sort by Newest',
'price-desc' => 'Sort by Price (High to Low)',
'price-asc' => 'Sort by Price (Low to High)',
'bedrooms-desc' => 'Sort by Beds (Most to Least)',
'bedrooms-asc' => 'Sort by Beds (Least to Most)'
];
?>

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<div class="filters_options">

  <select name="price_min" class="min_max_select">
    <option disabled="disabled" selected="" value="">Minimum Price</option>
    <?php foreach ($price_min as $key => $value) {
         $selected = '';
         if ($_GET['price_min'] == $key) {
             $selected = ' selected="selected"';
         }
         printf(
             '<option value="%s"%s>%s</option>',
             $key,
             $selected,
             $value
         );
     } ?>
  </select>

  <select name="price_max" class="min_max_select">
    <option disabled="disabled" selected="selected" value="">Maximum Price</option>
    <?php foreach ($price_max as $key => $value) {
         $selected = '';
         if ($_GET['price_max'] == $key) {
             $selected = ' selected="selected"';
         }
         printf(
             '<option value="%s"%s>%s</option>',
             $key,
             $selected,
             $value
         );
     } ?>
  </select>

  <select name="beds" class="select_beds">
    <option disabled="disabled" selected="selected" value="">Bedrooms</option>
    <?php foreach ($beds as $key => $value) {
         $selected = '';
         if ($_GET['beds'] == $key) {
             $selected = ' selected="selected"';
         }
         printf(
             '<option value="%s"%s>%s</option>',
             $key,
             $selected,
             $value
         );
     } ?>
  </select>

  <!-- <select>
    <option disabled="disabled" selected="selected" value="">Bathrooms</option>
    <option value="">All Baths</option>
    <option value="1+">1+</option>
    <option value="1+">2+</option>
    <option value="1+">3+</option>
    <option value="1+">4+</option>
    <option value="1+">5+</option>
  </select> -->

  <select name="type" class="sort_by_property_type">
    <option disabled="disabled" selected="selected" value="">Property Type</option>
    <?php foreach ($property_type as $key => $value) {
         $selected = '';
         if ($_GET['type'] == $key) {
             $selected = ' selected="selected"';
         }
         printf(
             '<option value="%s"%s>%s</option>',
             $key,
             $selected,
             $value
         );
     } ?>
  </select>

  <!-- <select>
    <option disabled="disabled" selected="selected" value="">Property View</option>
    <option value="">All Property Views</option>
    <option value="Golf View">Golf View</option>
    <option value="Ocean View">Ocean View</option>
    <option value="Ocean Front">Ocean Front</option>
  </select> -->

  <select name="sort_by" class="sort_by_dropdown">
    <?php
     foreach ($sort_by as $key => $value) {
         $selected = '';
         if ($_GET['sort_by'] == $key) {
             $selected = ' selected="selected"';
         }
         printf(
             '<option value="%s"%s>%s</option>',
             $key,
             $selected,
             $value
         );
     }
     ?>
  </select>

<input type="hidden" name="action" value="prop_filters" />
</div>

 <span class="reset_btn reset">reset</span>
<label class="done_btn" for="filter_toggle">Done</label>
</form> 
</div>

<ul id="main_posts" class="item-listings">
<?php 

//*
// Sort by Args
//*

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

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

    $per_page = 9;

    if(!empty( $_GET['page'])) {
        $per_page = $_GET['page'] * 9;
    }

// Build the inital Loop
$args = prepare_property_filters([
    'posts_per_page' => $per_page,
    'paged' => $_POST['page'],
    'meta_key' => $meta_key,
    'orderby' => $orderby,
    'order' => $order
]);

query_posts($args);

if( have_posts() ) :

    while( have_posts() ): the_post();

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

        $count_posts = $wp_query->found_posts; 

    endwhile;
endif;

?>
</ul>


<?php if (  $wp_query->max_num_pages > 1 ) :
    echo '<div id="prop_loadmore">More Listings</div>';
endif;?>

<span class="listings-count"><?php echo $count_posts;?> Real Estate Listings for Sale</span>
<!-- <span class="reset">reset</span> -->

  • Bitte stellen Sie uns die ausgelagerte kompilierte QUELLE zur Verfügung, damit ich sie sehen kann prop_loadmore_params Objekt

    – Abdelrahman Gobarah

    31. Januar 2020 um 10:50 Uhr

  • Entschuldigung, ich verstehe nicht, was das bedeutet?

    – Benutzer2115227

    31. Januar 2020 um 12:04 Uhr

  • URL: prop_loadmore_params.ajaxurl, diese Zeile von Ajax Function 3. Zeile muss es sehen prop_loadmore_params Objekt mit Werten

    – Abdelrahman Gobarah

    31. Januar 2020 um 12:32 Uhr

  • Ist diese Seite online hochgeladen? kannst du mir den link geben?

    – Abdelrahman Gobarah

    31. Januar 2020 um 12:38 Uhr

  • @user2115227 kannst du uns den Wert von zeigen prop_loadmore_params. Benutz einfach $(document).ready(function () {console.log(prop_loadmore_params) });

    – Aabir Hussain

    5. Februar 2020 um 16:46 Uhr

Dieser Codeblock wird ausgeführt, wenn #prop_loadmore geklickt wird:

var params = new URLSearchParams(location.search);
params.set('page', prop_loadmore_params.current_page);
window.history.replaceState({}, "", decodeURIComponent(`${location.pathname}?${params}`));

Du benutzt prop_loadmore_params die ihre aktuelle Seite erhöht, wenn auf die Schaltfläche geklickt wird, aber anscheinend keinen Verweis darauf hat price_min oder price_max

Du solltest dich anpassen $('#prop_loadmore').click(function(){...}) so etwas wie:

var params = new URLSearchParams(location.search);

params.set('page', prop_loadmore_params.current_page);

//Add All Additional Parameters in this way
if (prop_loadmore_params.price_min){
     params.set('price_min', prop_loadmore_params.price_min);
}
if (prop_loadmore_params.price_max){
     params.set('price_max', prop_loadmore_params.price_max);
}
// ...

window.history.replaceState({}, "", decodeURIComponent(`${location.pathname}?${params}`));

Und dann weiter $('#filter').change(function(){}) Stellen Sie sicher, dass Sie die gefilterten Werte zu hinzufügen prop_loadmore_params Objekt.

Lass mich wissen, wie es geht!

Du sendest POST mit AJAX aber Sie checken PHP mit ein $_GET[‘page’]

if (!empty($_GET['page'])) {
    $the_page = $_GET['page'];
}

Sie können verwenden $_REQUEST

Letztendlich habe ich das selbst gelöst. Ich tat es, indem ich die URL-Parameter in Variablen übergab, bevor das Loadmore-AJAX lief, etwas in dieser Richtung

var url_string = window.location;
var price_min = (new URL(url_string)).searchParams.get("price_min");
var price_max = (new URL(url_string)).searchParams.get("price_max");
var bedrooms = (new URL(url_string)).searchParams.get("beds");
var property_type = (new URL(url_string)).searchParams.get("type");
var sort_by = (new URL(url_string)).searchParams.get("sort_by");
var the_page = (new URL(url_string)).searchParams.get("page");

Dadurch funktionierte REQUEST beim Ajax-Aufruf beim Klicken auf die Schaltfläche “Mehr laden”.

1389810cookie-checkLassen Sie die AJAX-Paginierung beim Aktualisieren mit (AJAX-) URL-Filterparametern funktionieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy