1

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:

for 1 page of data it looks like this

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:

works fine like this for multiple pages

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?

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • FYI: I've edited your question to hopefully make it easier for readers to understand. Notably, I've rewritten the headline, fixed some minor punctuation issues, removed unnecessary tags (such as [tag:html]), and moved the images inline. This might help your question get more traction. – Jeremy Caney Jul 18 '21 at 22:52

1 Answers1

0

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.

Resolving exclusivity

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>';
    }
}       

Consolidating logic

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>';
    }
}

Refactoring for loop

This 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.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • 1
    Thank you very much for your time and experience! I understand now where was the issue and how the work can be much more simplified. Thank you again! – PaulCatalin Jul 21 '21 at 14:24
  • @PaulCatalin: No problem! I'm glad I could help. Aside, I'm sure you caught this, but I had accidentally included the `for` loop twice in my refactored code. That's obviously not needed or desired. I've updated the post to include that fix. – Jeremy Caney Jul 21 '21 at 20:49