0
votes

I'm making an online exam and I want to paginate the questions in different pages but the problem is that when I go to the next page the previous answers gone because the page refresh so how can I make the Laravel pagination withou refresh?

running Laravel 5.8

controller code:

$questions = $exam->questions()->paginate(1);
return view('exam.exam',compact('questions','exam'));
$questions = $exam->questions()->paginate(1);
return view('exam.exam',compact('questions','exam'));

view code

   {!! $questions->render() !!}
2

2 Answers

1
votes

This, sadly, can't be achieved without a little bit of asynchronous javascript - unless you want to preload all pages.

Your best bet is creating an API that returns paginated entries in a json format, then load it with javascript.

0
votes

finally i did it using vue.js and axios

app.js code :

data: {
        posts: {},
        pagination: {
            'current_page': 1
        }
    },

     methods: {
        fetchPosts() {
            axios.get('posts?page=' + this.pagination.current_page)
                .then(response => {
                    this.posts = response.data.data.data;
                    this.pagination = response.data.pagination;
                })
                .catch(error => {
                    console.log(error.response.data);
                });
        }
    },

    mounted() {
        this.fetchPosts();
    }
    
//and i added the pagination in a Component:

<template>
    <nav class="pagination is-centered" role="navigation" aria-label="pagination">
        <a class="pagination-previous" @click.prevent="changePage(1)" :disabled="pagination.current_page <= 1">First page</a>
        <a class="pagination-previous" @click.prevent="changePage(pagination.current_page - 1)" :disabled="pagination.current_page <= 1">Previous</a>
        <a class="pagination-next" @click.prevent="changePage(pagination.current_page + 1)" :disabled="pagination.current_page >= pagination.last_page">Next page</a>
        <a class="pagination-next" @click.prevent="changePage(pagination.last_page)" :disabled="pagination.current_page >= pagination.last_page">Last page</a>
        <ul class="pagination" style="display:block">
             <li v-for="page in pages">
                <a class="pagination-link" :class="isCurrentPage(page) ? 'is-current' : ''" @click.prevent="changePage(page)">{{ page }}</a>
            </li>
        </ul>
    </nav>
</template>

<style>
    .pagination {
        margin-top: 40px;
    }
</style>

<script>
    export default {
        props: ['pagination', 'offset'],

        methods: {
            isCurrentPage(page) {
                return this.pagination.current_page === page;
            },

            changePage(page) {
                if (page > this.pagination.last_page) {
                    page = this.pagination.last_page;
                }

                this.pagination.current_page = page;
                this.$emit('paginate');
            }
        },

        computed: {
            pages() {
                let pages = [];

                let from = this.pagination.current_page - Math.floor(this.offset / 2);

                if (from < 1) {
                    from = 1;
                }

                let to = from + this.offset - 1;

                if (to > this.pagination.last_page) {
                    to = this.pagination.last_page;
                }

                while (from <= to) {
                    pages.push(from);
                    from++;
                }

                return pages;
            }
        }
    }
</script>


<!-- begin snippet: js hide: false console: true babel: false -->
NOTE: this route will be used to return the pagination data into json only
Route::get('/posts', 'postContoller@pagination');

and in controller make a function to return the pagination information:

public function pagination(\App\post $post){
    $posts = $post->paginate(1);
    $response = [
        'pagination' => [
            'total' => $posts->total(),
            'per_page' => $posts->perPage(),
            'current_page' => $posts->currentPage(),
            'last_page' => $posts->lastPage(),
            'from' => $posts->firstItem(),
            'to' => $posts->lastItem()
        ],
        'data' => $posts
    ];
    return response()->json($response);
}      

now create a new view and paste this into

<div id="app">
 <div  v-for="post in posts">
    <div class="font-weight-bold p-4"> @{{post.qname}}</div>
 </div>
</div>

and create a route for it

Route::get('/', 'postController@index');