Jadikan Pagoda AJAX berfungsi dengan (AJAX) parameter filter URL saat refresh


9

Saya memiliki filter AJAX yang terdefinisi dengan baik, dalam dua bagian, satu untuk memuat lebih banyak tombol, dan satu untuk pilihan filter drop down. Keduanya memuat ulang daftar properti di front-end di AJAX, dan bekerja bersama secara bersamaan (mis. Jika saya memilih harga Min, harga maks dan jumlah tempat tidur dalam dropdown, daftar menyegarkan, dan memuat lebih banyak tombol berfungsi sebagaimana mestinya) .

Filter yang sama juga berfungsi dengan parameter URL. Jadi misalnya, jika URL-nya:

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

Itu akan menyaring oleh parameter tersebut. Itu bahkan menunjukkan 3 halaman senilai properti sebagaimana mestinya. Ini bekerja dengan baik, termasuk pada beban awal. Namun, itu tidak berfungsi dengan pagination, JIKA URL dimuat secara langsung. Jika saya memasukkan URL di atas secara langsung ke browser, dan memuat, hasil awal sudah benar, tetapi saat mengklik tombol Load More, itu mengubah halaman = 3 ke halaman = 4 (benar) tetapi menambahkan halaman kedua dari properti selesai tanpa filter. , dan terus melakukannya - daripada menjalankan pagination yang disaring.

Apa yang saya lakukan salah?

Ini kode saya (maaf itu banyak!)

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;

});

});

Functions.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();
}

dan HTML:

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

tolong berikan kami sumber outsourcing SOURCE yang dikompilasi sehingga saya dapat melihat objek prop_loadmore_params
Abdelrahman Gobarah

Maaf saya tidak mengerti apa artinya itu?
user2115227

url: prop_loadmore_params.ajaxurl, baris ini dari Ajax Function 3nd perlu melihat objek prop_loadmore_params dengan nilai
Abdelrahman Gobarah

apakah halaman ini diunggah secara online? dapatkah Anda memberikan saya tautannya?
Abdelrahman Gobarah

@ user2115227 dapatkah Anda menunjukkan nilai prop_loadmore_params. Cukup gunakan$(document).ready(function () {console.log(prop_loadmore_params) });
Aabir Hussain

Jawaban:


1

Blok kode ini dieksekusi ketika #prop_loadmorediklik:

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

Anda menggunakan prop_loadmore_paramskenaikan halaman mana saat ini ketika tombol diklik, tetapi tampaknya tidak memiliki referensiprice_min atauprice_max

Anda harus menyesuaikan $('#prop_loadmore').click(function(){...})untuk memasukkan sesuatu seperti:

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

Dan kemudian $('#filter').change(function(){})pastikan Anda menambahkan nilai yang difilter keprop_loadmore_params objek.

Biarkan saya tahu bagaimana kelanjutannya!


0

Anda mengirim POST dengan AJAX tetapi Anda memeriksa dalam PHP dengan $ _GET ['halaman']

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

Anda dapat menggunakan $ _REQUEST


0

Pada akhirnya, saya memecahkan ini sendiri. Cara saya melakukannya adalah dengan mengirimkan parameter URL ke variabel sebelum loadmore AJAX dijalankan, sesuatu di sepanjang baris ini

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");

Ini kemudian membuat REQUEST bekerja pada panggilan ajax dengan mengklik tombol load more

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.