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> -->
prop_loadmore_params
. Cukup gunakan$(document).ready(function () {console.log(prop_loadmore_params) });