サイトのページネーションを作成しようとしています。 ( 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
がobjJson.length
よりも大きい場合、someVar
ボタンを「隠す」方法を理解できません。
そして、「終わり」に達すると、nextPage
がobjJson
よりも小さくなると、someVar
ボタンが消えます。このコードの何が問題になっていますか?
完璧にするにはどうすれば変更できますか?私の悪い英語で申し訳ありません、私が必要なものすべてを説明することはできません。
質問がある場合は対処します...しかし、コードの重複を減らすために従うべき改善されたパターンを以下に示します。
補足として、notクライアント側でページネーションを行うことを検討する必要があります。巨大なデータセットがある場合、ページをロードする前にすべてのデータをダウンロードする必要があるためです。代わりにサーバー側のページネーションを実装することをお勧めします。
フィドル: 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);
};
UPDATE 2014/08/27
上記のバグがあります。特定のページ(通常、最後のページ)にrecords_per_page
個のレコードが含まれていない場合、存在しないインデックスにアクセスしようとするとforループがエラーになります。
修正は、objJson
のサイズを考慮してforループに追加のチェック条件を追加することにより、非常に簡単です。
更新されたフィドル: http://jsfiddle.net/Lzp0dw83/1/
for (var i = (page-1) * records_per_page; i < (page * records_per_page) && i < objJson.length; i++)
この要件を満たすコレクション一般のクラス構造を作成しました。次のようになります。
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()関数を使用してあなたが望む「ページ」(インデックス)を表示することです表示する。基本的に次のようになります。
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
私はあなたがすべてのページに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;
}
ページの読み込み時にデータが1回だけ取得される単純なクライアント側のページネーションの例。
// 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's 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})>«</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})>»</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>