Ajax Pagination – Phân trang bằng ajax cho wordpress sử dụng shortcode

Cập nhật lần cuối 28/12/2017 by trong WordPress vào 12/04/2015 có 764 Views

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

 

Download DEMO ONLINE

Để 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.phpajax_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">&laquo;</a></li>'; //first link
            $pagination .= '<li><a href="#" data-page="'.$previous_link.'" title="Previous">&lt;</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">&gt;</a></li>'; //next link
            $pagination .= '<li class="last"><a href="#" data-page="'.$total_pages.'" title="Last">&raquo;</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">&laquo;</a></li>'; //first link
            $pagination .= '<li><a href="#" data-page="'.$previous_link.'" title="Previous">&lt;</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">&gt;</a></li>'; //next link
            $pagination .= '<li class="last"><a href="#" data-page="'.$total_pages.'" title="Last">&raquo;</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!

 

DownloadDEMO ONLINE

Ajax Pagination – Phân trang bằng ajax cho wordpress sử dụng shortcode
4.7 (93.33%) 6 votes
  • Bình luận
Hosting nên dùng cho WordPress tại Việt Nam
Có thể bạn quan tâm
x