Простая разбивка на страницы в javascript

Я пытаюсь сделать разбивку на страницы для своего сайта. (http://anuntorhei.md)

CODE

var someVar = 50;


function someStupidFunction() {
        if (objJson.length > 50) {
                document.getElementById("nextPage").style.visibility = "visible";
        }

        if (someVar <= 50) {
                document.getElementById("prevPage").style.visibility ="hidden";
        } else {
                document.getElementById("prevPage").style.visibility = "visible";
        }
}


function nextPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar < objJson.length) {
                document.getElementById("nextPage").style.visibility = "visible";
        } else {
                document.getElementById("nextPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar += 50;

        document.getElementById("prevPage").style.visibility = "visible";
}


function prevPage() {
        document.getElementById("listingTable").innerHTML = "";

        if (someVar > 50) {
                document.getElementById("prevPage").style.visibility = "visible";
        } else {
                document.getElementById("prevPage").style.visibility = "hidden";
        }

        for (var i = someVar - 50; i < someVar; i++) {
                document.getElementById("listingTable").innerHTML += objJson[i].adName + "<br>";
        }

        someVar -= 50;

        document.getElementById("nextPage").style.visibility = "visible";
}

Но я не могу понять, как "скрыть" кнопку nextPage, когда someVar больше, чем objJson.length.

И когда я достигаю "конца", кнопка nextPage исчезает после <<25 > меньше someVar. Что не так в этом коде?

Как я могу изменить его, чтобы сделать его идеальным? Извините за мой плохой английский, не могу объяснить все, что мне нужно, надеюсь, что вы поймете, что мне нужно!

Ответ 1

Я рассмотрю любые вопросы, которые у вас есть... но вот улучшенный шаблон, который вы должны соблюдать, чтобы уменьшить дублирование кода.

В качестве обода, вы должны рассмотреть не выполнение разбиения на страницы на стороне клиента. Поскольку, если у вас огромный набор данных, это означает, что вам нужно загрузить все данные до загрузки страницы. Лучше выполнять разбиение на страницы на стороне сервера.

Fiddle: http://jsfiddle.net/Lzp0dw83/

HTML

<div id="listingTable"></div>
<a href="javascript:prevPage()" id="btn_prev">Prev</a>
<a href="javascript:nextPage()" id="btn_next">Next</a>
page: <span id="page"></span>

Javascript (помещается куда угодно):

var current_page = 1;
var records_per_page = 2;

var objJson = [
    { adName: "AdName 1"},
    { adName: "AdName 2"},
    { adName: "AdName 3"},
    { adName: "AdName 4"},
    { adName: "AdName 5"},
    { adName: "AdName 6"},
    { adName: "AdName 7"},
    { adName: "AdName 8"},
    { adName: "AdName 9"},
    { adName: "AdName 10"}
]; // Can be obtained from another source, such as your objJson variable

function prevPage()
{
    if (current_page > 1) {
        current_page--;
        changePage(current_page);
    }
}

function nextPage()
{
    if (current_page < numPages()) {
        current_page++;
        changePage(current_page);
    }
}

function changePage(page)
{
    var btn_next = document.getElementById("btn_next");
    var btn_prev = document.getElementById("btn_prev");
    var listing_table = document.getElementById("listingTable");
    var page_span = document.getElementById("page");

    // Validate page
    if (page < 1) page = 1;
    if (page > numPages()) page = numPages();

    listing_table.innerHTML = "";

    for (var i = (page-1) * records_per_page; i < (page * records_per_page); i++) {
        listing_table.innerHTML += objJson[i].adName + "<br>";
    }
    page_span.innerHTML = page;

    if (page == 1) {
        btn_prev.style.visibility = "hidden";
    } else {
        btn_prev.style.visibility = "visible";
    }

    if (page == numPages()) {
        btn_next.style.visibility = "hidden";
    } else {
        btn_next.style.visibility = "visible";
    }
}

function numPages()
{
    return Math.ceil(objJson.length / records_per_page);
}

window.onload = function() {
    changePage(1);
};

ОБНОВЛЕНИЕ 2014/08/27

Существует ошибка, в которой ошибки цикла for отсутствуют, когда определенная страница (обычно последняя страница) не содержит records_per_page количества записей, поскольку она пытается получить доступ к несуществующему индексу.

Исправление достаточно просто, добавив дополнительное условие проверки в цикл for для учета размера objJson:

Обновлен скрипт: http://jsfiddle.net/Lzp0dw83/1/

for (var i = (page-1) * records_per_page; i < (page * records_per_page) && i < objJson.length; i++)

Ответ 2

Я создал структуру классов для коллекций в целом, которая отвечала бы этому требованию. и это выглядит так:

class Collection {

    constructor() {
        this.collection = [];
        this.index = 0;
    }

    log() {
        return console.log(this.collection);
    }

    push(value) {
        return this.collection.push(value);
    }

    pushAll(...values) {
        return this.collection.push(...values);
    }

    pop() {
        return this.collection.pop();
    }

    shift() {
        return this.collection.shift();
    }

    unshift(value) {
        return this.collection.unshift(value);
    }

    unshiftAll(...values) {
        return this.collection.unshift(...values);
    }

    remove(index) {
        return this.collection.splice(index, 1);
    }

    add(index, value) {
        return this.collection.splice(index, 0, value);
    }

    replace(index, value) {
        return this.collection.splice(index, 1, value);
    }

    clear() {
        this.collection.length = 0;
    }

    isEmpty() {
        return this.collection.length === 0;
    }

    viewFirst() {
        return this.collection[0];
    }

    viewLast() {
        return this.collection[this.collection.length - 1];
    }

    current(){
        if((this.index <= this.collection.length - 1) && (this.index >= 0)){
            return this.collection[this.index];
        }
        else{
            return 'Object index exceeds collection range.';
        }
    }

    next() {
        this.index++;
        this.index > this.collection.length - 1 ? this.index = 0 : this.index;
        return this.collection[this.index];
    }

    previous(){
        this.index--;
        this.index < 0 ? (this.index = this.collection.length-1) : this.index;
        return this.collection[this.index];
    }
}

... и, по сути, вы должны иметь коллекцию массивов любой длины для ваших страниц, помещенных в объект класса, а затем использовать функции next() и previous() для отображения любой страницы (index) ) вы хотели показать. По сути, будет выглядеть так:

let books = new Collection();
let firstPage - [['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'], ['dummyData'],];
let secondPage - [['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'], ['dumberData'],];
books.pushAll(firstPage, secondPage); // loads each array individually
books.current() // display firstPage
books.next() // display secondPage

Ответ 3

я предполагаю, что вы будете отображать 10 данных на каждой странице

HTML: -

<!DOCTYPE html>
<html>
<head>
    <title>pagination</title>
    <link rel="stylesheet"  href="pathofcssfile.css">
</head>
<body>
    <div>
        <table id="user"></table>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <ul>
    <li value="1">1</li>
    <li value="2">2</li>
    <li value="3">3</li>
    <li value="4">4</li>
    <li value="5">5</li>
    <li value="6">6</li>
    <li value="7">7</li>
    <li value="8">8</li>
    <li value="9">9</li>
    <li value="10">10</li>

    </ul>

    <script src="pathnameofjsfile.js" type="text/javascript"></script>
</body>
</html>

JS: -

var xhr = new XMLHttpRequest();
xhr.open('GET',"https://jsonplaceholder.typicode.com/albums",true);
xhr.send();

var udata;

xhr.onload = function() 
{
    if(this.status == 200) 
    {
        var userdata = JSON.parse(this.responseText);
        console.log(userdata);
        udata = userdata;
        data(1);
    }
}

$("li").click(function ()
{       
var a = $(this).attr("value");
console.log("value li "+ a);
data(a);
});

function data(a)
{  
    var output = "";
    for(i=((a-1)*10);i<(a*10);i++)
    {
        output +='<tr>'+
                 '<td>'+ udata[i].userId + '</td>'+
                 '<td>'+ udata[i].id + '</td>'+
                 '<td>'+ udata[i].title + '</td>'+ '<br>'
                 '</tr>';
    }
    document.getElementById('user').innerHTML = output;
}

CSS: -

ul{
display: flex;
list-style-type:none;
padding: 20px;
}

li{
padding: 20px;
}

td,tr{
    padding: 10px;
}

Ответ 4

Простой пример разбиения на страницы на стороне клиента, когда данные загружаются только один раз при загрузке страницы.

// dummy data
        const myarr = [{ "req_no": 1, "title": "test1" },
        { "req_no": 2, "title": "test2" },
        { "req_no": 3, "title": "test3" },
        { "req_no": 4, "title": "test4" },
        { "req_no": 5, "title": "test5" },
        { "req_no": 6, "title": "test6" },
        { "req_no": 7, "title": "test7" },
        { "req_no": 8, "title": "test8" },
        { "req_no": 9, "title": "test9" },
        { "req_no": 10, "title": "test10" },
        { "req_no": 11, "title": "test11" },
        { "req_no": 12, "title": "test12" },
        { "req_no": 13, "title": "test13" },
        { "req_no": 14, "title": "test14" },
        { "req_no": 15, "title": "test15" },
        { "req_no": 16, "title": "test16" },
        { "req_no": 17, "title": "test17" },
        { "req_no": 18, "title": "test18" },
        { "req_no": 19, "title": "test19" },
        { "req_no": 20, "title": "test20" },
        { "req_no": 21, "title": "test21" },
        { "req_no": 22, "title": "test22" },
        { "req_no": 23, "title": "test23" },
        { "req_no": 24, "title": "test24" },
        { "req_no": 25, "title": "test25" },
        { "req_no": 26, "title": "test26" }];

        // on page load collect data to load pagination as well as table
        const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };

        // At a time maximum allowed pages to be shown in pagination div
        const pagination_visible_pages = 4;


        // hide pages from pagination from beginning if more than pagination_visible_pages
        function hide_from_beginning(element) {
            if (element.style.display === "" || element.style.display === "block") {
                element.style.display = "none";
            } else {
                hide_from_beginning(element.nextSibling);
            }
        }
        
        // hide pages from pagination ending if more than pagination_visible_pages
        function hide_from_end(element) {
            if (element.style.display === "" || element.style.display === "block") {
                element.style.display = "none";
            } else {
                hide_from_beginning(element.previousSibling);
            }
        }
        
        // load data and style for active page
        function active_page(element, rows, req_per_page) {
            var current_page = document.getElementsByClassName('active');
            var next_link = document.getElementById('next_link');
            var prev_link = document.getElementById('prev_link');
            var next_tab = current_page[0].nextSibling; 
            var prev_tab = current_page[0].previousSibling;
            current_page[0].className = current_page[0].className.replace("active", "");
            if (element === "next") {
                if (parseInt(next_tab.text).toString() === 'NaN') {
                    next_tab.previousSibling.className += " active";
                    next_tab.setAttribute("onclick", "return false");
                } else {
                    next_tab.className += " active"
                    render_table_rows(rows, parseInt(req_per_page), parseInt(next_tab.text));
                    if (prev_link.getAttribute("onclick") === "return false") {
                        prev_link.setAttribute("onclick", 'active_page('prev',\"${rows}\",${req_per_page})');
                    }
                    if (next_tab.style.display === "none") {
                        next_tab.style.display = "block";
                        hide_from_beginning(prev_link.nextSibling)
                    }
                }
            } else if (element === "prev") {
                if (parseInt(prev_tab.text).toString() === 'NaN') {
                    prev_tab.nextSibling.className += " active";
                    prev_tab.setAttribute("onclick", "return false");
                } else {
                    prev_tab.className += " active";
                    render_table_rows(rows, parseInt(req_per_page), parseInt(prev_tab.text));
                    if (next_link.getAttribute("onclick") === "return false") {
                        next_link.setAttribute("onclick", 'active_page('next',\"${rows}\",${req_per_page})');
                    }
                    if (prev_tab.style.display === "none") {
                        prev_tab.style.display = "block";
                        hide_from_end(next_link.previousSibling)
                    }
                }
            } else {
                element.className += "active";
                render_table_rows(rows, parseInt(req_per_page), parseInt(element.text));
                if (prev_link.getAttribute("onclick") === "return false") {
                    prev_link.setAttribute("onclick", 'active_page('prev',\"${rows}\",${req_per_page})');
                }
                if (next_link.getAttribute("onclick") === "return false") {
                    next_link.setAttribute("onclick", 'active_page('next',\"${rows}\",${req_per_page})');
                }
            }
        }

        // Render the table row in table request-table
        function render_table_rows(rows, req_per_page, page_no) {
            const response = JSON.parse(window.atob(rows));
            const resp = response.slice(req_per_page * (page_no - 1), req_per_page * page_no)
            $('#request-table').empty()
            $('#request-table').append('<tr><th>Index</th><th>Request No</th><th>Title</th></tr>');
            resp.forEach(function (element, index) {
                if (Object.keys(element).length > 0) {
                    const { req_no, title } = element;
                    const td = '<tr><td>${++index}</td><td>${req_no}</td><td>${title}</td></tr>';
                    $('#request-table').append(td)
                }
            });
        }

        // Pagination logic implementation
        function pagination(data, myarr) {
            const all_data = window.btoa(JSON.stringify(myarr));
            $(".pagination").empty();
            if (data.req_per_page !== 'ALL') {
                let pager = '<a href="#" id="prev_link" onclick=active_page('prev',\"${all_data}\",${data.req_per_page})>&laquo;</a>' +
                    '<a href="#" class="active" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>1</a>';
                const total_page = Math.ceil(parseInt(myarr.length) / parseInt(data.req_per_page));
                if (total_page < pagination_visible_pages) {
                    render_table_rows(all_data, data.req_per_page, data.page_no);
                    for (let num = 2; num <= total_page; num++) {
                        pager += '<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>';
                    }
                } else {
                    render_table_rows(all_data, data.req_per_page, data.page_no);
                    for (let num = 2; num <= pagination_visible_pages; num++) {
                        pager += '<a href="#" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>';
                    }
                    for (let num = pagination_visible_pages + 1; num <= total_page; num++) {
                        pager += '<a href="#" style="display:none;" onclick=active_page(this,\"${all_data}\",${data.req_per_page})>${num}</a>';
                    }
                }
                pager += '<a href="#" id="next_link" onclick=active_page('next',\"${all_data}\",${data.req_per_page})>&raquo;</a>';
                $(".pagination").append(pager);
            } else {
                render_table_rows(all_data, myarr.length, 1);
            }
        }

        //calling pagination function
        pagination(data, myarr);


        // trigger when requests per page dropdown changes
        function filter_requests() {
            const data = { "req_per_page": document.getElementById("req_per_page").value, "page_no": 1 };
            pagination(data, myarr);
        }
.box {
	float: left;
	padding: 50px 0px;
}

.clearfix::after {
	clear: both;
	display: table;
}

.options {
	margin: 5px 0px 0px 0px;
	float: left;
}

.pagination {
	float: right;
}

.pagination a {
	color: black;
	float: left;
	padding: 8px 16px;
	text-decoration: none;
	transition: background-color .3s;
	border: 1px solid #ddd;
	margin: 0 4px;
}

.pagination a.active {
	background-color: #4CAF50;
	color: white;
	border: 1px solid #4CAF50;
}

.pagination a:hover:not(.active) {
	background-color: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
    <table id="request-table">
   </table>
</div>

<div class="clearfix">
	<div class="box options">
		<label>Requests Per Page: </label>
      <select id="req_per_page" onchange="filter_requests()">
			<option>5</option>
			<option>10</option>
			<option>ALL</option>
		</select>
	</div>
	<div class="box pagination">
	</div>
</div>

Ответ 5


function Pagination(pageEleArr, numOfEleToDisplayPerPage) {
    this.pageEleArr = pageEleArr;
    this.numOfEleToDisplayPerPage = numOfEleToDisplayPerPage;
    this.elementCount = this.pageEleArr.length;
    this.numOfPages = Math.ceil(this.elementCount / this.numOfEleToDisplayPerPage);
    const pageElementsArr = function (arr, eleDispCount) {
        const arrLen = arr.length;
        const noOfPages = Math.ceil(arrLen / eleDispCount);
        let pageArr = [];
        let perPageArr = [];
        let index = 0;
        let condition = 0;
        let remainingEleInArr = 0;

        for (let i = 0; i < noOfPages; i++) {

            if (i === 0) {
                index = 0;
                condition = eleDispCount;
            }
            for (let j = index; j < condition; j++) {
                perPageArr.push(arr[j]);
            }
            pageArr.push(perPageArr);
            if (i === 0) {
                remainingEleInArr = arrLen - perPageArr.length;
            } else {
                remainingEleInArr = remainingEleInArr - perPageArr.length;
            }

            if (remainingEleInArr > 0) {
                if (remainingEleInArr > eleDispCount) {
                    index = index + eleDispCount;
                    condition = condition + eleDispCount;
                } else {
                    index = index + perPageArr.length;
                    condition = condition + remainingEleInArr;
                }
            }
            perPageArr = [];
        }
        return pageArr;
    }
    this.display = function (pageNo) {
        if (pageNo > this.numOfPages || pageNo <= 0) {
            return -1;
        } else {
            console.log('Inside else loop in display method');
            console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage));
            console.log(pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1]);
            return pageElementsArr(this.pageEleArr, this.numOfEleToDisplayPerPage)[pageNo - 1];
        }
    }
}

const p1 = new Pagination(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3);
console.log(p1.elementCount);
console.log(p1.pageEleArr);
console.log(p1.numOfPages);
console.log(p1.numOfEleToDisplayPerPage);
console.log(p1.display(3));