Reputation: 13
I'm using a table to show the values from my database and I use a JQuery for pagination. This is working overall. When there is only one page of results, however, the pagination shows:
This isn't what I want; the link to Page 1 should only be displayed once.
When it shows data for more pages, it works fine:
Here is the code for the table and the buttons
function getProducts() {
$.get('/get-products', parameters).then(res => {
console.log(res);
let products = res.data;
preview = res.current_page > 1 ? true : false;
next = res.current_page < res.last_page ? true : false;
preview ? $('#previous').removeAttr("disabled") : $('#previous').attr('disabled', 'disabled');
next ? $('#next').removeAttr("disabled") : $('#next').attr('disabled', 'disabled');
let table_body = $('#tbody');
table_body.empty();
var html = '';
$.each(products, function(index, val) {
html += "<tr> " +
"<td>" + val.name + "</td>" +
"<td>" + val.quantity + "</td>" +
"<td>" + val.price +"<p> Lei </p>"+"</td>" +
"<td>" + val.status.name + "</td>" +
"<td>" + val.description + "</td>" +
"<td>" + val.technics + "</td>" +
"<td>" + "<a class='btn btn-warning' href='/editareprodus/"+ val.id +"'>Edit</a>" + "</td>" +
"<td>" + "<a class='btn btn-danger' onclick=deleteItem("+ val.id +")>Delete</a>" + "</td>" +
"</tr>";
});
table_body.append(html);
$('.page_button').remove();
var buttons = '';
for(var i = 1; i < res.last_page+1; i++) {
if(i == 1) {
if(i == res.current_page) {
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
} else{
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
}
}
if(i == res.last_page) {
if(i == res.current_page) {
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
} else{
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
}
}
if(i == res.current_page-2 && res.current_page-2 >= 2 ) {
buttons += '<span class="page_button">...</span>';
}
if(i == res.current_page+2 && res.current_page+2 < res.last_page) {
buttons += '<span class="page_button">...</span>';
}
if((i != 1 && i != res.last_page) && (i == res.current_page-1 || i == res.current_page || i == res.current_page+1)) {
if(i == res.current_page) {
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
} else {
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter('+i+')">'+i+'</button>';
}
}
}
$('#previous').after(buttons)
});
}
I will add the code for the previous and next page button just so you can see them, but these work fine:
function previewPage() {
if(preview) {
parameters.page--;
getProducts();
}
}
function nextPage() {
if(next) {
parameters.page++;
getProducts();
}
}
function setPageParameter(page) {
this.parameters.page = page;
getProducts();
}
How can I change the code to show me one page button when I have one page, not two buttons as is happening now?
Upvotes: 0
Views: 682
Reputation: 7625
The issue is due to a problem with the logic within your for
loop. You have several conditions under which a button can be written:
If the button is the first page; i.e.,
i == 1
If the button is the last page; i.e.,
i == res.last_page
If the button is immediately before or after the current page, but not the first or the last page; i.e.,
(i != 1 && i != res.last_page) && (i == res.current_page-1 || i == res.current_page || i == res.current_page+1)
The key issue is that the first two are non-exclusive; i.e., when you only have one page, your button can simultaneously represent both the first page as well as the last page. Thus, it's fully expected that you'd see two buttons in that scenario.
This can easily be resolved by simply changing the logic of the second condition from an if
to an else if
; e.g.,
if (i == 1)
{
if (i == res.current_page) {
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
else
{
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
}
else if (i == res.last_page) // Only show if not also the first button
{
if (i == res.current_page)
{
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
else
{
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
}
The above solves your core issue, but as these generate the exact same markup, you might as well collapse them into a single condition using an ||
operator, thus maintaining the same results while consolidating the code:
if (i == 1 || i == res.last_page)
{
if (i == res.current_page)
{
buttons += '<button type="button" class="btn btn-danger page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
else
{
buttons += '<button type="button" class="btn btn-primary page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
}
for
loopThis is well beyond the scope of your original question, but even after consolidating the previous conditions, there's still room for cleanup. That's because, currently, you're repeating a lot of markup within your function.
As a developer, you should strive not to repeat code. Why? Because in addition to making the code longer, it can also make it easier to introduce bugs. For example, if you decide to change the style of the buttons, you need to change them in four places. It’s easy in that situation to inadvertently overlook one, introducing an inconsistency.
Given that, you should be able to further consolidate your logic as something like the following:
for (var i = 1; i < res.last_page + 1; i++) {
if (i == 1 || i == res.last_page || i == res.current_page - 1 || i == res.current_page || i == res.current_page + 1) {
buttons += '<span class="page_button">...</span>';
}
else if (
(i == res.current_page - 2 && res.current_page - 2 >= 2) ||
(i == res.current_page + 2 && res.current_page + 2 < res.last_page)
) {
buttons += '<button type="button" class="btn btn-"' + (i == res.current_page? "danger" : "primary") + '" page_button" onclick="setPageParameter(' + i + ')">' + i + '</button>';
}
}
This logic could be simplified a bit more, but I've maintained your original expressions for consistency and readability, while refactoring them to avoid the duplication of markup. This not only addresses the original issue, but results in much shorter code block.
Upvotes: 0