0

I am fairly new to Laravel and now i need to implement ajax functionality to my project. I got it how to display article and create it via ajax, problem occurs when i need to list them. And that has two sub-problems.

  1. Display paginated articles which i did
  2. and second one which is changing to next page with new set of articles. I know how to do this with laravel's pagination, but in this case, pagination also should be done with ajax.

I got some data that i take from ArticlesController which sends json response which looks like this:

{
    status: "success", msg: "Hello!", articles: {…}, request: {…}}
    articles:
    current_page: 1
    data: Array(1)
    0: {id: 3, title: "Post1", body: "<p><strong>Lorem ipsum</strong> dolor sit amet, co…ctum. Duis feugiat facilisis lectus a cursus.</p>", created_at: "2019-06-18 00:23:25", updated_at: "2019-06-18 18:33:52", …}
    length: 1
    __proto__: Array(0)
    first_page_url: "http://articleapp.test/postajax?page=1"
    from: 1
    last_page: 3
    last_page_url: "http://articleapp.test/postajax?page=3"
    next_page_url: "http://articleapp.test/postajax?page=2"
    path: "http://articleapp.test/postajax"
    per_page: 1
    prev_page_url: null
    to: 1
    total: 3
    __proto__: Object
    msg: "Hello!"
    request: {_token: "T31VK2FBVbIBG6IIOK4X4Q0r7WPTlzc7haXCwJrM", message: "bravo"}
    status: "success"
    __proto__: Object
}

Controller method which after received call from ajax function, gathers data and sends it back as json response. One part of that data is paginated records of Articles table:

public function ajaks(Request $request){

        if($request->ajax()){
            $articles = Article::with('user')->paginate(1);

            $response = array(
                'status' => 'success',
                'msg' => "Hello!",
                "articles" => $articles,
                "request" => $request->all(),  
            );

            return response()->json($response);

        }

   }

Ajax function it send request through predetermined route alongside csrf token and in turn receive response. From that response, it constructs html which is afterwards appended to particular div in my layouts blade. Her is ajax function:

function ajaks(/*par*/){
    let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
    console.log("hit");
    $.ajax({
        url: '/postajax',
        type: 'POST',
        data: {_token: token , message: "bravo"},
        dataType: 'JSON',
        success: (response) => { 
            console.log("success");
            console.log(response);
            let body = "";
            let html = "<div class='container'>";

            let len = response.articles.data.length;
            for(let i=0;i<len;i++){

                html += "<div class='row' style='background-color: whitesmoke;'><div class='col-md-4 col-sm-4'><a href='/articles/"+response.articles.data[i].id+"'><img class='postCover postCoverIndex' src='/storage/images/"+response.articles.data[i].image+"'></a></div><div class='col-md-8 col-sm-8'><br>";

                if(response.articles.data[i].body.length > 400){
                    body = response.articles.data[i].body.substring(0, 400)+"<a href='/articles/"+response.articles.data[i].id+"'>...Read more</a>";
                }
                else{
                    body = response.articles.data[i].body;
                }

                html += "<p>"+body+"</p>";
                html += "<small class='timestamp'>Written on "+response.articles.data[i].created_at+" by "+response.articles.data[i].user.name+"</small></div></div><hr class='hrStyle'>";
            }

            let pagination = "<div class='container'><ul class='pagination justify-content-center'><li class='page-item'><a class='page-link' href='#'>Previous</a></li>";
            for(let i=0;i<response.articles.last_page;i++){
                pagination += "<li class='page-item'><a class='page-link' href='#'>"+(i+1)+"</a></li>";
            }
            pagination += "<li class='page-item'><a class='page-link' href='#'>Next</a></li></ul></div>";


            //console.log(pagination);
            html += "</div>"+"<form id='pagForm'>"+pagination+"</form>";

            if(document.getElementById("maine")){

                    document.getElementById("maine").innerHTML = html;
            }
        },
        error: (response) => {
            console.log("error");
            console.log(response);
        }
    }); 

}

And with this, i'm checking for ajax route and getting first set of articles:

<?php
if(Route::getFacadeRoot()->current()->uri()=="ajax"){
?>
<script>
    $(document).ready(function(){
        ajaks();
    });
</script>
<?php
}
?>

it is in my layouts blade. Also pagination links are just plain bootstrap, it just helps me visualize. My question is how i can use this for pagination? What is the correct approach for using ajax since i can't rely on Laravel's built-in pagination for this. Should i attach another ajax function onto pagination links which then would call controller method again? And when controller method receives such via request, how to use that on pagination in controller method?

1 Answer 1

1

You can actually use Laravel's built in pagination via ajax pretty easily, you just need to pass the page in the request. The paginate function will detect the requested page and handle the results automatically.

function ajaks(p){
    p = typeof p === 'number' && p > 0 ? p : 1;
    let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
    console.log("hit");
    $.ajax({
        url: '/postajax',
        type: 'POST',
        data: {_token: token , message: "bravo", page: p},
...

As you pointed out, you will also need to capture clicks on the pagination links, stop the regular click event from propigating and redirect it to your function like this ...

$(document).on('click', '.pagination a', function(e){
  e.preventDefault();
  var p = $(this).attr('href').split('page=')[1];
  ajaks(p);
});

This assumes standard laravel pagination links that have page=x as a query param. You could pretty easily add this to your existing pagination routine or my trick is usually to render the html in my controller and pass that back in my ajax response, like this ...

$articles = Article::with('user')->paginate(1);
$response = array(
  'status' => 'success',
  'msg' => "Hello!",
  "articles" => $articles,
  "request" => $request->all(),
  'pagination' => (string)$articles->links()
);

And then render it in the browser ...

$('#pagination').html(response.pagination);
Sign up to request clarification or add additional context in comments.

2 Comments

Did it, but used loop generated pagination, instead href attribute, i captured its innerHTML by using jquery's text(). Like this: var page = $(this).html(); Only left is how to give functionality to prev and next buttons. And i did it by accident. Didn't know of your solution at the time, when you send page value through data.page
Actually your solution is better than mein(concerning pagination). Will apply.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.