😅Sử dụng async, await, bất đồng bộ lấy dữ liệu Pagination, sử dụng Deferred 👌 phần 2 (ok)
https://stackoverflow.com/questions/23355168/jquery-recursive-ajax-call-promise
Last updated
https://stackoverflow.com/questions/23355168/jquery-recursive-ajax-call-promise
Last updated
ajax.php
<?php
$products = array(
array(
'id' => '1',
'title' => 'Product 1',
'sku' => 'code-2',
'price' => '95.00',
'category' => 'Shirts',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '2',
'title' => 'Product 2',
'sku' => 'code-2',
'price' => '145.00',
'category' => 'Pants',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '3',
'title' => 'Product 3',
'sku' => 'code-3',
'price' => '895.00',
'category' => 'Shirts',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '4',
'title' => 'Product 4',
'sku' => 'code-4',
'price' => '295.00',
'category' => 'Pants',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '5',
'title' => 'Product 5',
'sku' => 'code-5',
'price' => '215.00',
'category' => 'Caps',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '6',
'title' => 'Product 6',
'sku' => 'code-6',
'price' => '365.00',
'category' => 'Shirts',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '7',
'title' => 'Product 7',
'sku' => 'code-7',
'price' => '95.00',
'category' => 'Caps',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '8',
'title' => 'Product 8',
'sku' => 'code-8',
'price' => '495.00',
'category' => 'Caps',
'image' => 'https://via.placeholder.com/500x300.png'
),
array(
'id' => '9',
'title' => 'Product 9',
'sku' => 'code-9',
'price' => '95.00',
'category' => 'Caps',
'image' => 'https://via.placeholder.com/500x300.png'
),
);
// Declare $filtered_products array to store products in the filter $_GET params
$filtered_products = array();
// Declare $categories array to store categories
$categories = array();
// Loop through products and store categories into categories array. Also store filtered products into an array
foreach ($products as $product) {
// Make sure item has a category key and a value, assigned as key and value to prevent duplicates
if ($product['category'] && !empty($product['category'])) {
$categories[$product['category']] = $product['category'];
}
//Store filtered products if set
if (isset($_GET['category']) && !empty($_GET['category']) && $product['category'] == $_GET['category']) {
$filtered_products[] = $product;
}
}
// Get the total products based on filter must come AFTER the loop above
$total_products = isset($_GET['category']) && !empty($_GET['category']) ? count($filtered_products) : count($products);
// Declare a variable for our current page. If no page is set, the default is page 1
$current_page = isset($_GET['page']) ? $_GET['page'] : 1;
// Declare $limit value this can either be another filter option, a value pulled from the database (like user preferences) or a fixed value
$limit = 2;
// Declare an offset based on our current page (if we're not on page 1).
if (!empty($current_page) && $current_page > 1) {
$offset = ($current_page * $limit) - $limit;
/*
for example, if we are on page 3 and we're only showing 2 items per page, we've already seen four items, two on page 1 and two on page 2. So our next number should be 5.
We need to offset by 4.
(3 * 2) - 2
3 * 2 = 6, 6 - 2 = 4 (so we offset the value by 4 )
*/
} else {
$offset = 0;
}
// Get the total pages rounded up the nearest whole number
$total_pages = ceil($total_products / $limit);
// Declare active category filter to use when we paginate so we don't lose the filter
$filtered_category_query = isset($_GET['category']) ? '&category=' . $_GET['category'] : '';
// When we filter, we want to know the range of products we're viewing
$first_product_displayed = $offset + 1;
//example : if we're on page 3, our offset is 4 ( limit(page 1) + limit(page2) ) so 4 + 1 = 5 (first product in view is 5)
// if the total products is more than the current offset x 2 + 2 then our last product is the offset + 2 or else it should be the total
$last_product_displayed = $total_products >= ($offset * $limit) + $limit ? $offset + $limit : $total_products;
// example 1 : if we're on page 3, our offset is 4 ( limit(page 1) + limit(page2) ) so 4 x 2 = 8, + 2 = 10 (last product in view is 10)
// example 2 : if we're on page 2, our offset is 2 ( limit(page 2) ) so 2 x 2 = 4, + 2 = 6 (last product in view is 6)
// Display the current range in view
if ($first_product_displayed === $last_product_displayed) {
$range = 'the Last of ' . $total_products . ' Products';
} else {
$range = $first_product_displayed . ' - ' . $last_product_displayed . ' of ' . $total_products . ' Products';
}
?>
<?php
// Redefine $products array if there are filters set
if (isset($_GET['category']) && !empty($_GET['category'])) {
// Array Slice allows us to offset and limit array output
$products = array_slice($filtered_products, $offset, $limit);
}
// or leave as is
else {
$products = array_slice($products, $offset, $limit);
}
// Loop through $products array
echo json_encode($products);
?>
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Blog Home - Start Bootstrap Template</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body>
<script type="text/javascript">
function fetch(opt_offset,opt_result,defer) {
var offset = opt_offset || 1;
var result = opt_result || [];
return $.ajax({
url: 'https://lva.com/ajax.php?page=' + offset,
type: 'GET',
dataType: 'json',
success: function(response) {
result = result.concat(response);
if(response.length == 2) {
fetch(offset+1,result,defer);
}else {
defer.resolve(result);
}
}
});
}
function requestAll(){
var deferred = jQuery.Deferred();
fetch(null, [], deferred);
return deferred.promise();
}
requestAll().done(function(items) {
console.log(items);
});
</script>
</body>
</html>