Skip to main content
How Can We Help?
Pagination with Divi 5 Loop
Step by Step guideline to add pagination in Divi 5 Loop layout:
Step 1: Setup the loop layout. Make sure to label the loop item properly, so that we can target that through the pagination module.
Step 2: Add the Pagination module and select the loop that you want to connect. No class/ID needed for this procedure.
Step 3: Paste the script from the attached file in script.js file.
Step 4: Paste the CSS from attached file in style.css file.
Now the pagination is ready with the AJAX. It will work dynamically.
//pagination fix
document.addEventListener('DOMContentLoaded', function () {
const selector = '.et_pb_posts_nav[data-target-loop]';
let ajaxRunning = false;
function getPage(url, loopId) {
try {
return parseInt(
new URL(url, window.location.href).searchParams.get(loopId),
10
) || 1;
} catch (e) {
return 1;
}
}
function getItems(loopId, doc) {
return Array.from(
doc.querySelectorAll(
'[data-loop-item][data-loop-source="' + loopId + '"]'
)
);
}
function bindAjax(link, pagination) {
if (!link || link.dataset.ajaxBound === '1') {
return;
}
link.dataset.ajaxBound = '1';
link.addEventListener('click', function (e) {
e.preventDefault();
loadPage(pagination, link.href);
});
}
function updatePagination(pagination, source, currentPage) {
const loopId = pagination.dataset.targetLoop;
const sourcePrev = source.querySelector('.nav-previous a');
const sourceNext = source.querySelector('.nav-next a');
/*
* Create Previous container if it does not exist
*/
let prevBox = pagination.querySelector('.nav-previous');
if (!prevBox && sourcePrev) {
prevBox = document.createElement('span');
prevBox.className = 'nav-previous';
prevBox.innerHTML =
'<a href="' + sourcePrev.href + '">' +
'<span class="meta-nav">↠</span>' +
'<span class="nav-label">Previous</span>' +
'</a>';
pagination.insertBefore(
prevBox,
pagination.firstChild
);
}
/*
* Update Previous
*/
if (prevBox) {
if (sourcePrev) {
const prevLink = prevBox.querySelector('a');
if (prevLink) {
prevLink.href = sourcePrev.href;
}
prevBox.style.display = '';
bindAjax(prevLink, pagination);
} else {
prevBox.style.display = 'none';
}
}
/*
* Create Next container if needed
*/
let nextBox = pagination.querySelector('.nav-next');
if (!nextBox && sourceNext) {
nextBox = document.createElement('span');
nextBox.className = 'nav-next';
nextBox.innerHTML =
'<a href="' + sourceNext.href + '">' +
'<span class="nav-label">Next</span>' +
'<span class="meta-nav"> →</span>' +
'</a>';
pagination.appendChild(nextBox);
}
/*
* Update Next
*/
if (nextBox) {
if (sourceNext) {
const nextLink = nextBox.querySelector('a');
if (nextLink) {
nextLink.href = sourceNext.href;
}
nextBox.style.display = '';
bindAjax(nextLink, pagination);
} else {
nextBox.style.display = 'none';
}
}
/*
* Remove old page numbers
*/
const oldNumbers =
pagination.querySelector('.custom-page-numbers');
if (oldNumbers) {
oldNumbers.remove();
}
/*
* Create page numbers
*/
const numbers = document.createElement('span');
numbers.className = 'custom-page-numbers';
function addNumber(page, url, current) {
const link = document.createElement('a');
link.href = url || '#';
link.textContent = page;
link.className = 'custom-page-number';
if (current) {
link.classList.add('current');
link.setAttribute('aria-current', 'page');
} else {
bindAjax(link, pagination);
}
numbers.appendChild(link);
}
/*
* Previous page number
*/
if (currentPage > 1 && sourcePrev) {
addNumber(
currentPage - 1,
sourcePrev.href,
false
);
}
/*
* Current page
*/
addNumber(
currentPage,
null,
true
);
/*
* Next page number
*/
if (sourceNext) {
const nextPage = getPage(
sourceNext.href,
loopId
);
addNumber(
nextPage,
sourceNext.href,
false
);
}
/*
* Insert numbers between Previous and Next
*/
if (nextBox) {
pagination.insertBefore(
numbers,
nextBox
);
} else {
pagination.appendChild(numbers);
}
}
function replaceItems(pagination, newDoc) {
const loopId = pagination.dataset.targetLoop;
const oldItems = getItems(loopId, document);
const newItems = getItems(loopId, newDoc);
if (!oldItems.length || !newItems.length) {
return false;
}
const parent = oldItems[0].parentElement;
if (!parent) {
return false;
}
const fragment = document.createDocumentFragment();
newItems.forEach(function (item) {
fragment.appendChild(
item.cloneNode(true)
);
});
oldItems.forEach(function (item) {
item.remove();
});
parent.appendChild(fragment);
return true;
}
function loadPage(pagination, url) {
if (ajaxRunning) {
return;
}
ajaxRunning = true;
pagination.classList.add(
'pagination-loading'
);
fetch(url, {
method: 'GET',
credentials: 'same-origin'
})
.then(function (response) {
if (!response.ok) {
throw new Error();
}
return response.text();
})
.then(function (html) {
const doc =
new DOMParser().parseFromString(
html,
'text/html'
);
const loopId =
pagination.dataset.targetLoop;
const newPagination =
doc.querySelector(
'.et_pb_posts_nav[data-target-loop="' +
loopId +
'"]'
);
if (!newPagination) {
window.location.href = url;
return;
}
if (!replaceItems(pagination, doc)) {
window.location.href = url;
return;
}
const currentPage =
getPage(url, loopId);
updatePagination(
pagination,
newPagination,
currentPage
);
window.history.pushState(
{
loopPage: currentPage
},
'',
url
);
const firstItem =
getItems(loopId, document)[0];
if (firstItem) {
window.scrollTo({
top:
firstItem.getBoundingClientRect().top +
window.pageYOffset -
100,
behavior: 'smooth'
});
}
})
.catch(function () {
window.location.href = url;
})
.finally(function () {
ajaxRunning = false;
pagination.classList.remove(
'pagination-loading'
);
});
}
function initialize(pagination) {
const loopId =
pagination.dataset.targetLoop;
if (!loopId) {
return;
}
updatePagination(
pagination,
pagination,
getPage(
window.location.href,
loopId
)
);
}
document
.querySelectorAll(selector)
.forEach(function (pagination) {
initialize(pagination);
});
/*
* Browser Back / Forward
*/
window.addEventListener('popstate', function () {
document
.querySelectorAll(selector)
.forEach(function (pagination) {
loadPage(
pagination,
window.location.href
);
});
});
});
/**Pagination fix**/
body #page-container .et_pb_posts_nav,
body #page-container .et_pb_posts_nav .custom-page-numbers,
body #page-container .et_pb_posts_nav .custom-page-number,
body #page-container .et_pb_posts_nav .custom-page-prev{
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
body #page-container .et_pb_posts_nav .nav-next {
margin-left: unset;
}
body #page-container .et_pb_posts_nav a{
padding: 12px 10px;
border: 1px solid;
line-height: 1em;
width: 40px;
height: 40px;
transition: all .3s ease;
}
body #page-container .et_pb_posts_nav a:hover,
body #page-container .et_pb_posts_nav a.current{
background: #10512a;
color: #fff !important;
border: 1px solid #10512a;
}
body #page-container .et_pb_posts_nav a:hover > .meta-nav{
color: #fff !important;
}
body #page-container .et_pb_posts_nav a .meta-nav,
body #page-container .et_pb_posts_nav .nav-label{
display: none;
}
body #page-container .et_pb_posts_nav .nav-previous a,
body #page-container .et_pb_posts_nav .nav-next a{
position: relative !important;
margin: 0 !important;
display: flex;
}
body #page-container .et_pb_posts_nav .nav-previous a:before,
body #page-container .et_pb_posts_nav .nav-next a:before{
content: "\34";
font-family: ETmodules;
color: #10512a;
line-height: 1em !important;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: inherit;
}
body #page-container .et_pb_posts_nav .nav-next a:before{
content: "\35";
}
@media (max-width: 980px){
body #page-container .et_pb_posts_nav a{
height: 35px;
width: 35px;
}
}