Trong bài này mình sẽ giới thiệu tới mọi người 1 cách để phân trang bằng ajax khi lấy dữ liệu như bài post hoặc page.
Sau khi hoàn thiện bài hướng dẫn này chúng ta có được shortcode dạng [ajax_pagination] Trong shortcode này chúng ta có các thông số như sau.
[ajax_pagination post_type="post" posts_per_page="5" paged="1"]
post_type: slug của post, page hoặc custom post type.
posts_per_page: Số lượng bài hiển thị trên một trang
paged: bắt đầu từ page số mấy. cái này không cần cũng được
Để duy trì blog nên mình có làm aff cho 1 số bên hosting. Nhưng dù aff mình cũng chọn 1 số nhà cung cấp uy tín về chất lượng và support nên các bạn cứ yên tâm nhé.
Nếu có mua hosting mà có trong list dưới đây các bạn click vào link trước khi mua để ủng hộ mình nhé. Mình cảm ơn nhiều
- Azdigi: Giá rẻ thì dùng gói Pro Gold Hosting còn chất lượng hơn thì em khuyên dùng Business Hosting. Có điều kiện thì lên VPS nhé
- Tino hosting
- iNet
- Nước ngoài thì Vultr
Để gọn gàng, dễ hiểu và sau này có thể mở rộng thành plugin thì mình sẽ cho tất cả code của bài vào folder AjaxPagination và bên trong đó sẽ có các file ajax_pagination_wp.php, ajax_pagination.js và Ajax_pagination.css
Folder AjaxPagination sẽ để ở ngay thư mục theme của bạn (wp-contents/themes/[your-theme]/AjaxPagination) và nhớ include vào file functions.php của theme chúng ta đang làm việc.
/* * Thêm dòng này vào file functions.php của theme */ include 'AjaxPagination/ajax_pagination_wp.php';
Và bây giờ chúng ta sẽ đi vào chi tiết từng file như sau:
Shortcode hiển thị dữ liệu
Tạo file ajax_pagination_wp.php trong folder AjaxPagination nói bên trên. Sau đó gán đoạn code bên dưới này vào
/******************* * Load Post via ajax with Pagination - Query post * Author: Le Van Toan - www.levantoan.com ********************/ /****************** * Thêm shortcode ajax_pagination ********************/ function ajax_pagination_svl( $atts ){ $atts = shortcode_atts( array( 'posts_per_page' => 5, 'paged' => 1, 'post_type' => 'post' ), $atts,'ajax_pagination' ); $posts_per_page = intval($atts['posts_per_page']); $paged = intval($atts['paged']); $post_type = sanitize_text_field($atts['post_type']); $allpost = '<div id="result_ajaxp">'; $allpost .= query_ajax_pagination( $post_type, $posts_per_page , $paged ); $allpost .= '</div>'; return $allpost; } add_shortcode('ajax_pagination', 'ajax_pagination_svl'); function query_ajax_pagination( $post_type = 'post', $posts_per_page = 5, $paged = 1){ $args_svl = array( 'post_type' => $post_type, 'posts_per_page' => $posts_per_page, 'paged' => $paged, 'post_status' => 'publish' ); $q_svl = new WP_Query( $args_svl ); /*Tổng bài viết trong query trên*/ $total_records = $q_svl->found_posts; /*Tổng số page*/ $total_pages = ceil($total_records/$posts_per_page); if($q_svl->have_posts()): $allpost = '<div class="ajax_pagination" posts_per_page="'.$posts_per_page.'" post_type="'.$post_type.'">'; while($q_svl->have_posts()):$q_svl->the_post(); $allpost .= '<div class="ajaxp_list_post">'; $allpost .= '<a href="'.get_permalink().'" title="'.get_the_title().'">'.get_the_title().'</a> - <span>'.get_the_date().'</span>'; $allpost .= '</div>'; endwhile; $allpost .= '</div>'; $allpost .= paginate_function( $posts_per_page, $paged, $total_records, $total_pages); $allpost .='<div class="loading_ajaxp"><div id="circularG"><div id="circularG_1" class="circularG"></div><div id="circularG_2" class="circularG"></div><div id="circularG_3" class="circularG"></div><div id="circularG_4" class="circularG"></div><div id="circularG_5" class="circularG"></div><div id="circularG_6" class="circularG"></div><div id="circularG_7" class="circularG"></div><div id="circularG_8" class="circularG"></div></div></div>'; endif;wp_reset_query(); return $allpost; }
Code phân trang PHP. Dạng 1,2,3…
Đoạn code này giúp chúng ta có phân trang dạng 1,2,3….Hãy copy và dán đoạn code này vào tiếp file ajax_pagination_wp.php bên trên nhé.
/****************** Function phân trang PHP có dạng 1,2,3 ... ********************/ function paginate_function($item_per_page, $current_page, $total_records, $total_pages) { $pagination = ''; if($total_pages > 0 && $total_pages != 1 && $current_page <= $total_pages){ //verify total pages and current page number $pagination .= '<ul class="pagination">'; $right_links = $current_page + 3; $previous = $current_page - 3; //previous link $next = $current_page + 1; //next link $first_link = true; //boolean var to decide our first link if($current_page > 1){ $previous_link = ($previous==0)?1:$previous; $pagination .= '<li class="first"><a href="#" data-page="1" title="First">«</a></li>'; //first link $pagination .= '<li><a href="#" data-page="'.$previous_link.'" title="Previous"><</a></li>'; //previous link for($i = ($current_page-2); $i < $current_page; $i++){ //Create left-hand side links if($i > 0){ $pagination .= '<li><a href="#" data-page="'.$i.'" title="Page'.$i.'">'.$i.'</a></li>'; } } $first_link = false; //set first link to false } if($first_link){ //if current active page is first link $pagination .= '<li class="first active">'.$current_page.'</li>'; }elseif($current_page == $total_pages){ //if it's the last active link $pagination .= '<li class="last active">'.$current_page.'</li>'; }else{ //regular current link $pagination .= '<li class="active">'.$current_page.'</li>'; } for($i = $current_page+1; $i < $right_links ; $i++){ //create right-hand side links if($i<=$total_pages){ $pagination .= '<li><a href="#" data-page="'.$i.'" title="Page '.$i.'">'.$i.'</a></li>'; } } if($current_page < $total_pages){ $next_link = ($i > $total_pages)? $total_pages : $i; $pagination .= '<li><a href="#" data-page="'.$next_link.'" title="Next">></a></li>'; //next link $pagination .= '<li class="last"><a href="#" data-page="'.$total_pages.'" title="Last">»</a></li>'; //last link } $pagination .= '</ul>'; } return $pagination; //return pagination links }
Js và css trong hướng dẫn này
Dưới đây là đoạn js để gửi thông số và nhận kết quả mà ajax gửi ra để hiển thị.
/******* Author LeVanToan - https://levantoan.com *********/ // JavaScript Document (function($) { $(document).ready(function(){ $( '#result_ajaxp' ).on( 'click',' ul.pagination a', function( e ) { /** Prevent Default Behaviour */ e.preventDefault(); /** Get data-page */ var data_page = $(this).attr( 'data-page' ); var posts_per_page = $('.ajax_pagination').attr( 'posts_per_page' ); var post_type = $('.ajax_pagination').attr( 'post_type' ); /** Ajax Call */ $.ajax({ cache: false, timeout: 8000, url: svl_array_ajaxp.admin_ajax, type: "POST", data: ({ action : 'LoadPostPagination', data_page : data_page, posts_per_page : posts_per_page, post_type : post_type }), beforeSend: function() { $( '.loading_ajaxp' ).css( 'display','block' ); }, success: function( data, textStatus, jqXHR ){ $( '#result_ajaxp' ).html( data ); }, error: function( jqXHR, textStatus, errorThrown ){ console.log( 'The following error occured: ' + textStatus, errorThrown ); }, complete: function( jqXHR, textStatus ){ } }); }); }); })(jQuery);
Còn css các bạn tham khảo thêm ở file đính kèm nha
Gọi và xử lý ajax trong WordPress
Hàm này giúp các bạn load dữ liệu bằng ajax. Để biết thêm về ajax trong worpress bạn tham khảo thêm bài này: Sử dụng ajax trong wordpress
/** Xử lý Ajax trong WordPress */ add_action( 'wp_ajax_LoadPostPagination', 'LoadPostPagination_init' ); add_action( 'wp_ajax_nopriv_LoadPostPagination', 'LoadPostPagination_init' ); function LoadPostPagination_init() { $posts_per_page = intval($_POST['posts_per_page']); $paged = intval($_POST['data_page']); $post_type = sanitize_text_field($_POST['post_type']); $allpost = query_ajax_pagination( $post_type, $posts_per_page , $paged ); echo $allpost; exit; }
Thêm jQuery và Css vào Web thông qua function
Đoạn code này để gọi file js và css vào theme.
add_action( 'wp_enqueue_scripts', 'devvn_useAjaxPagination', 1 ); function devvn_useAjaxPagination() { /** Thêm js vào website */ wp_enqueue_script( 'devvn-ajax', esc_url( trailingslashit( get_stylesheet_directory_uri() ) . 'AjaxPagination/ajax_pagination.js' ), array( 'jquery' ), '1.0', true ); $php_array = array( 'admin_ajax' => admin_url( 'admin-ajax.php' ) ); wp_localize_script( 'devvn-ajax', 'svl_array_ajaxp', $php_array ); /*Thêm css vào website*/ wp_enqueue_style( 'ajaxp', esc_url( trailingslashit( get_stylesheet_directory_uri() )) . 'AjaxPagination/Ajax_pagination.css', false); }
Code hoàn thiện
File ajax_pagination_wp.php
<?php /******************* * Load Post via ajax with Pagination - Query post * Author: Le Van Toan - www.levantoan.com ********************/ /****************** * Thêm shortcode ajax_pagination ********************/ function ajax_pagination_svl( $atts ){ $atts = shortcode_atts( array( 'posts_per_page' => 5, 'paged' => 1, 'post_type' => 'post' ), $atts,'ajax_pagination' ); $posts_per_page = intval($atts['posts_per_page']); $paged = intval($atts['paged']); $post_type = sanitize_text_field($atts['post_type']); $allpost = '<div id="result_ajaxp">'; $allpost .= query_ajax_pagination( $post_type, $posts_per_page , $paged ); $allpost .= '</div>'; return $allpost; } add_shortcode('ajax_pagination', 'ajax_pagination_svl'); function query_ajax_pagination( $post_type = 'post', $posts_per_page = 5, $paged = 1){ $args_svl = array( 'post_type' => $post_type, 'posts_per_page' => $posts_per_page, 'paged' => $paged, 'post_status' => 'publish' ); $q_svl = new WP_Query( $args_svl ); /*Tổng bài viết trong query trên*/ $total_records = $q_svl->found_posts; /*Tổng số page*/ $total_pages = ceil($total_records/$posts_per_page); if($q_svl->have_posts()): $allpost = '<div class="ajax_pagination" posts_per_page="'.$posts_per_page.'" post_type="'.$post_type.'">'; while($q_svl->have_posts()):$q_svl->the_post(); $allpost .= '<div class="ajaxp_list_post">'; $allpost .= '<a href="'.get_permalink().'" title="'.get_the_title().'">'.get_the_title().'</a> - <span>'.get_the_date().'</span>'; $allpost .= '</div>'; endwhile; $allpost .= '</div>'; $allpost .= paginate_function( $posts_per_page, $paged, $total_records, $total_pages); $allpost .='<div class="loading_ajaxp"><div id="circularG"><div id="circularG_1" class="circularG"></div><div id="circularG_2" class="circularG"></div><div id="circularG_3" class="circularG"></div><div id="circularG_4" class="circularG"></div><div id="circularG_5" class="circularG"></div><div id="circularG_6" class="circularG"></div><div id="circularG_7" class="circularG"></div><div id="circularG_8" class="circularG"></div></div></div>'; endif;wp_reset_query(); return $allpost; } /****************** Function phân trang PHP có dạng 1,2,3 ... ********************/ function paginate_function($item_per_page, $current_page, $total_records, $total_pages) { $pagination = ''; if($total_pages > 0 && $total_pages != 1 && $current_page <= $total_pages){ //verify total pages and current page number $pagination .= '<ul class="pagination">'; $right_links = $current_page + 3; $previous = $current_page - 3; //previous link $next = $current_page + 1; //next link $first_link = true; //boolean var to decide our first link if($current_page > 1){ $previous_link = ($previous==0)?1:$previous; $pagination .= '<li class="first"><a href="#" data-page="1" title="First">«</a></li>'; //first link $pagination .= '<li><a href="#" data-page="'.$previous_link.'" title="Previous"><</a></li>'; //previous link for($i = ($current_page-2); $i < $current_page; $i++){ //Create left-hand side links if($i > 0){ $pagination .= '<li><a href="#" data-page="'.$i.'" title="Page'.$i.'">'.$i.'</a></li>'; } } $first_link = false; //set first link to false } if($first_link){ //if current active page is first link $pagination .= '<li class="first active">'.$current_page.'</li>'; }elseif($current_page == $total_pages){ //if it's the last active link $pagination .= '<li class="last active">'.$current_page.'</li>'; }else{ //regular current link $pagination .= '<li class="active">'.$current_page.'</li>'; } for($i = $current_page+1; $i < $right_links ; $i++){ //create right-hand side links if($i<=$total_pages){ $pagination .= '<li><a href="#" data-page="'.$i.'" title="Page '.$i.'">'.$i.'</a></li>'; } } if($current_page < $total_pages){ $next_link = ($i > $total_pages)? $total_pages : $i; $pagination .= '<li><a href="#" data-page="'.$next_link.'" title="Next">></a></li>'; //next link $pagination .= '<li class="last"><a href="#" data-page="'.$total_pages.'" title="Last">»</a></li>'; //last link } $pagination .= '</ul>'; } return $pagination; //return pagination links } /** Xử lý Ajax trong WordPress */ add_action( 'wp_ajax_LoadPostPagination', 'LoadPostPagination_init' ); add_action( 'wp_ajax_nopriv_LoadPostPagination', 'LoadPostPagination_init' ); function LoadPostPagination_init() { $posts_per_page = intval($_POST['posts_per_page']); $paged = intval($_POST['data_page']); $post_type = sanitize_text_field($_POST['post_type']); $allpost = query_ajax_pagination( $post_type, $posts_per_page , $paged ); echo $allpost; exit; } add_action( 'wp_enqueue_scripts', 'devvn_useAjaxPagination', 1 ); function devvn_useAjaxPagination() { /** Thêm js vào website */ wp_enqueue_script( 'devvn-ajax', esc_url( trailingslashit( get_stylesheet_directory_uri() ) . 'AjaxPagination/ajax_pagination.js' ), array( 'jquery' ), '1.0', true ); $php_array = array( 'admin_ajax' => admin_url( 'admin-ajax.php' ) ); wp_localize_script( 'devvn-ajax', 'svl_array_ajaxp', $php_array ); /*Thêm css vào website*/ wp_enqueue_style( 'ajaxp', esc_url( trailingslashit( get_stylesheet_directory_uri() )) . 'AjaxPagination/Ajax_pagination.css', false); }
File Ajax_pagination.css
/******* Author LeVanToan - https://levantoan.com *********/ ul.pagination li { list-style: none; float: left; margin: 0; padding: 0; } ul.pagination li a { padding: 5px 10px; display: block; } ul.pagination li.active { padding: 5px 10px; } div#result_ajaxp { position: relative; display: table; } div#result_ajaxp:after { display: table; content: " "; clear: both; } /*CSS load*/ #circularG { position: relative; width: 30px; height: 30px; left: 50%; top: 50%; margin-left: -25px; margin-top: -25px; } .circularG { position: absolute; background-color: #000000; width: 7px; height: 7px; -moz-border-radius: 5px; -moz-animation-name: bounce_circularG; -moz-animation-duration: 0.56s; -moz-animation-iteration-count: infinite; -moz-animation-direction: normal; -webkit-border-radius: 5px; -webkit-animation-name: bounce_circularG; -webkit-animation-duration: 0.56s; -webkit-animation-iteration-count: infinite; -webkit-animation-direction: normal; -ms-border-radius: 5px; -ms-animation-name: bounce_circularG; -ms-animation-duration: 0.56s; -ms-animation-iteration-count: infinite; -ms-animation-direction: normal; -o-border-radius: 5px; -o-animation-name: bounce_circularG; -o-animation-duration: 0.56s; -o-animation-iteration-count: infinite; -o-animation-direction: normal; border-radius: 5px; animation-name: bounce_circularG; animation-duration: 0.56s; animation-iteration-count: infinite; animation-direction: normal; } #circularG_1 { left: 0; top: 12px; -moz-animation-delay: 0.21s; -webkit-animation-delay: 0.21s; -ms-animation-delay: 0.21s; -o-animation-delay: 0.21s; animation-delay: 0.21s; } #circularG_2 { left: 3px; top: 3px; -moz-animation-delay: 0.28s; -webkit-animation-delay: 0.28s; -ms-animation-delay: 0.28s; -o-animation-delay: 0.28s; animation-delay: 0.28s; } #circularG_3 { top: 0; left: 12px; -moz-animation-delay: 0.35s; -webkit-animation-delay: 0.35s; -ms-animation-delay: 0.35s; -o-animation-delay: 0.35s; animation-delay: 0.35s; } #circularG_4 { right: 3px; top: 3px; -moz-animation-delay: 0.42s; -webkit-animation-delay: 0.42s; -ms-animation-delay: 0.42s; -o-animation-delay: 0.42s; animation-delay: 0.42s; } #circularG_5 { right: 0; top: 12px; -moz-animation-delay: 0.49s; -webkit-animation-delay: 0.49s; -ms-animation-delay: 0.49s; -o-animation-delay: 0.49s; animation-delay: 0.49s; } #circularG_6 { right: 3px; bottom: 3px; -moz-animation-delay: 0.56s; -webkit-animation-delay: 0.56s; -ms-animation-delay: 0.56s; -o-animation-delay: 0.56s; animation-delay: 0.56s; } #circularG_7 { left: 12px; bottom: 0; -moz-animation-delay: 0.63s; -webkit-animation-delay: 0.63s; -ms-animation-delay: 0.63s; -o-animation-delay: 0.63s; animation-delay: 0.63s; } #circularG_8 { left: 3px; bottom: 3px; -moz-animation-delay: 0.7s; -webkit-animation-delay: 0.7s; -ms-animation-delay: 0.7s; -o-animation-delay: 0.7s; animation-delay: 0.7s; } @-moz-keyframes bounce_circularG { 0% { -moz-transform: scale(1) } 100% { -moz-transform: scale(.3) } } @-webkit-keyframes bounce_circularG { 0% { -webkit-transform: scale(1) } 100% { -webkit-transform: scale(.3) } } @-ms-keyframes bounce_circularG { 0% { -ms-transform: scale(1) } 100% { -ms-transform: scale(.3) } } @-o-keyframes bounce_circularG { 0% { -o-transform: scale(1) } 100% { -o-transform: scale(.3) } } @keyframes bounce_circularG { 0% { transform: scale(1) } 100% { transform: scale(.3) } } .loading_ajaxp { position: absolute; width: 100%; height: 100%; top: 0; left: 0; text-align: center; background: rgba(0, 0, 0, 0.05); display: none; }
File ajax_pagination.js
/******* Author LeVanToan - https://levantoan.com *********/ // JavaScript Document (function($) { $(document).ready(function(){ $( '#result_ajaxp' ).on( 'click',' ul.pagination a', function( e ) { /** Prevent Default Behaviour */ e.preventDefault(); /** Get data-page */ var data_page = $(this).attr( 'data-page' ); var posts_per_page = $('.ajax_pagination').attr( 'posts_per_page' ); var post_type = $('.ajax_pagination').attr( 'post_type' ); /** Ajax Call */ $.ajax({ cache: false, timeout: 8000, url: svl_array_ajaxp.admin_ajax, type: "POST", data: ({ action : 'LoadPostPagination', data_page : data_page, posts_per_page : posts_per_page, post_type : post_type }), beforeSend: function() { $( '.loading_ajaxp' ).css( 'display','block' ); }, success: function( data, textStatus, jqXHR ){ $( '#result_ajaxp' ).html( data ); }, error: function( jqXHR, textStatus, errorThrown ){ console.log( 'The following error occured: ' + textStatus, errorThrown ); }, complete: function( jqXHR, textStatus ){ } }); }); }); })(jQuery);
Chúc các bạn thành công!
- Bình luận