The number of records displays on the page affect the load time of a webpage.
To improve response time you can show limited records at a time using pagination.
There are various types of pagination available.
One of them is a load-more type.
It adds new records at the end when it gets clicked until records are found.
In this tutorial, I show how you can implement load more functionality on your webpage with Vue.js and PHP.
Contents
1. Table structure
Create posts
table and added some records.
CREATE TABLE `posts` ( `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `title` varchar(100) NOT NULL, `content` text NOT NULL, `link` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. Configuration
Create a config.php
for the database connection.
Completed Code
<?php $host = "localhost"; /* Host name */ $user = "root"; /* User */ $password = ""; /* Password */ $dbname = "tutorial"; /* Database name */ $con = mysqli_connect($host, $user, $password,$dbname); // Check connection if (!$con) { die("Connection failed: " . mysqli_connect_error()); }
3. HTML
Create the layout using <div >
and use v-for
to loop on posts
variable and retrieve data.
Define the click
event on <h1 >
which call getPosts()
method and add v-bind:class="[isFinished ? 'finish' : 'load-more']"
to change class according to isFinished
value.
Include vue.js
and axios.min.js
scripts.
You can download the Axios package from here or you can also use CDN (https://unpkg.com/axios/dist/axios.min.js).
The script.js
file contains Vue.js code which creates in the Script section.
Completed Code
<!-- CSS --> <link href='style.css' rel='stylesheet' type='text/css' > <!-- Posts List --> <div class="container" id='myapp'> <!-- Post --> <div class="post" v-for='post in posts'> <h2 v-cloak>{{ post.title }}</h2> <p v-cloak> {{ post.shortcontent }} </p> <a :href="post.link" class="more" target="_blank" v-cloak>More</a> </div> <!-- Load More --> <h2 v-bind:class="[isFinished ? 'finish' : 'load-more']" @click='getPosts()' v-cloak>{{ buttonText }}</h2> </div> <!-- Script --> <script src="vue.js"></script> <script src="axios-master/dist/axios.min.js"></script> <script src="script.js"></script>
4. CSS
Create a new style.css
file.
.container{ width: 55%; margin: 0 auto; border: 0px solid black; padding: 10px 0px; } /* post */ .post{ width: 97%; min-height: 200px; padding: 5px; border: 1px solid gray; margin-bottom: 15px; } .post h1{ letter-spacing: 1px; font-weight: normal; font-family: sans-serif; } .post p{ letter-spacing: 1px; text-overflow: ellipsis; line-height: 25px; } /* Load more */ .load-more{ width: 99%; background: #15a9ce; text-align: center; color: white; padding: 10px 0px; font-family: sans-serif; } .load-more:hover{ cursor: pointer; } /* Finish */ .finish{ width: 99%; background: darkgray; text-align: center; color: white; padding: 10px 0px; font-family: sans-serif; } /* more link */ .more{ color: blue; text-decoration: none; letter-spacing: 1px; font-size: 16px; } [v-cloak] { display:none; }
5. PHP
Create ajaxfile.php
.
Read POST row
and rowperpage
value.
Use these values in the SELECT query to fetch records from posts
table.
Loop on the fetched records and initialize $response_arr
array.
Return $response_arr
in JSON format.
Completed Code
<?php // configuration include 'config.php'; $data = json_decode(file_get_contents("php://input")); $row = $data->row; $rowperpage = $data->rowperpage; // Fetch records $query = 'SELECT * FROM posts LIMIT '.$row.','.$rowperpage; $result = mysqli_query($con,$query); $response_arr = array(); while($datarow = mysqli_fetch_assoc($result)){ $id = $datarow['id']; $title = $datarow['title']; $content = $datarow['content']; $shortcontent = substr($content, 0, 160)."..."; $link = $datarow['link']; $response_arr[] = array( 'id'=>$id, 'title'=>$title, 'shortcontent'=>$shortcontent, 'content'=>$content, 'link'=>$link ); } echo json_encode($response_arr); exit;
6. Script
Create a new script.js
file.
Define the following data variables –
- isFinished – Use this variable to check whether records are available or not.
- row – Fetch records position. Assigned value 0.
- rowperpage – Number of records fetch per request. Assigned value 3.
- buttonText – This is used to change the <h1 > text.
- posts – Store response from AJAX request.
Create a getPosts
method.
Send AJAX POST request to ajaxfile.php
where pass row
and rowerpage
values as data.
On successful callback check response.data
is empty is not.
If not empty then update app.row
value and check app.posts
length. If length returns 0 then directly assign response.data
in app.posts
otherwise, change buttonText
value and loop on response.data
to add data in app.posts
.
If response.data
is empty then assign true
to app.isFinished
and update app.buttonText
value to "No more records available"
.
Use created
option to call getPosts
method after instance created.
Completed Code
var app = new Vue({ el: '#myapp', data: { isFinished: false, row: 0, // Record selction position rowperpage: 3, // Number of records fetch at a time buttonText: 'Load More', posts: '' }, methods: { getPosts: function(){ axios.post('ajaxfile.php', { row: this.row, rowperpage: this.rowperpage }) .then(function (response) { if(response.data !='' ){ // Update rowperpage app.row+=app.rowperpage; var len = app.posts.length; if(len > 0){ app.buttonText = "Loading ..."; setTimeout(function() { app.buttonText = "Load More"; // Loop on data and push in posts for (let i = 0; i < response.data.length; i++){ app.posts.push(response.data[i]); } },500); }else{ app.posts = response.data; } }else{ app.buttonText = "No more records avaiable."; app.isFinished = true; } }); } }, created: function(){ this.getPosts(); } })
7. Demo
8. Conclusion
I have assigned 3 to rowperpage
data variable which you can modify according to requirement.
Pass additional value from Axios request if you want to also filter records and also update the AJAX file accordingly.
If you found this tutorial helpful then don't forget to share.