I'm currently working on incorporating pagination into a table showcasing data for Magic: The Gathering cards.
By default, the table displays only 5 items per page, with options to select pages and set the number of results per page at the bottom of the screen. Navigation is facilitated through "Next Page" and "Previous Page" buttons.
const app = new Vue({
el: "#app",
data: {
apiUrl: "https://api.magicthegathering.io/v1/cards",
cards: [],
pageNumber: 1,
resultsPerPage: 5,
dropdownResultsPerPage: 5,
increments: [5, 10, 15, 20, 25]
},
created: function() {
var vue = this;
axios
.get(this.apiUrl)
.then(function(data) {
vue.cards = data.data.cards;
})
.catch(function(error) {
console.log(error);
});
},
computed: {
startIndex: function() {
return (this.pageNumber - 1) * this.resultsPerPage;
},
endIndex: function() {
return this.startIndex + this.dropdownResultsPerPage;
},
numberOfPages: function() {
return Math.ceil(this.cards.length / this.dropdownResultsPerPage);
},
paginatedData: function() {
return this.cards.slice(this.startIndex, this.endIndex);
}
},
methods: {
nextPage: function() {
this.pageNumber++;
},
previousPage: function() {
this.pageNumber--;
}
}
});
body {
overflow: hidden;
}
#header {
display: flex;
position: sticky;
border-bottom: 1px solid black;
}
#app .content {
overflow: auto;
height: 300px;
position: relative;
}
#pagination: {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
box-shadow: 0px 0px 6px 2px #fafafa;
}
[v-cloak] {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.8/vue.min.js"></script>
<div id="header">
<h1>MTG Cards</h1>
</div>
<div id="app" v-cloak>
<div class="content">
<table>
<thead>
<th>Id</th>
<th>Name</th>
<th>Mana Cost</th>
</thead>
<tbody>
<tr v-for="(card, index) in paginatedData" :key="index">
<td>{{ card.id }}</td>
<td>{{ card.name }}</td>
<td>{{ card.manaCost }}</td>
</tr>
</tbody>
</table>
</div>
<div id="pagination">
<p>
Page:
<select v-model="pageNumber">
<option v-for="(page, index) in numberOfPages" :key="index" :value="page">
{{ page }}
</option>
</select>
of {{ numberOfPages }}
<button @click="previousPage" :disabled="pageNumber == 1">
Previous
</button>
<button @click="nextPage" :disabled="pageNumber >= numberOfPages">
Next
</button> |
<select v-model="dropdownResultsPerPage">
<option v-for="(increment, index) in increments" :key="index" :value="increment">
{{ increment }}
</option>
</select>
cards per page
</p>
</div>
</div>
Assuming you have set resultsPerPage
to 5
, giving you a total of 100
pages.
If you navigate to page 5 out of 20 and then change the value of resultsPerPage
to 25
, the total number of pages changes from 20 to 4. However, as you are already on page 5, the Page Number dropdown does not reflect this change, making navigation confusing.
Is there a way to update the visual page number while keeping the same results displayed in the table?