PdoPage без jQuery
Давно делал костылями пагинацию без jQuery
недавно дошли руки поковырять PdoPage
Скажу сразу в скрипте могут быть баги
У меня с ресурсами работает отлично
Замените assets/components/pdotools/js/pdopage.min.js
Стартый лучше на всякий случай перименуйте пусть будет на такой
недавно дошли руки поковырять PdoPage
Скажу сразу в скрипте могут быть баги
У меня с ресурсами работает отлично
Стартый лучше на всякий случай перименуйте пусть будет на такой
if (typeof(pdoPage) == 'undefined') {
pdoPage = {callbacks: {}, keys: {}, configs: {}};
}
pdoPage.Reached = false;
pdoPage.initialize = function (config) {
if (pdoPage.keys[config['pageVarKey']] == undefined) {
var tkey = config['pageVarKey'];
var tparams = pdoPage.Hash.get();
var tpage = tparams[tkey] == undefined ? 1 : tparams[tkey];
pdoPage.keys[tkey] = Number(tpage);
pdoPage.configs[tkey] = config;
}
switch (config['mode']) {
case 'default':
document.addEventListener('click', function(e) {
// Используем closest для поиска радителя
var target = e.target.closest(config['link']);
if (target) {
e.preventDefault();
var href = target.getAttribute('href');
var key = config['pageVarKey'];
if (!href) {
console.error('href is undefined');
return;
}
var match = href.match(new RegExp(key + '=(\\d+)'));
var page = !match ? 1 : match[1];
if (pdoPage.keys[key] != page) {
if (config.history) {
if (page == 1) {
pdoPage.Hash.remove(key);
} else {
pdoPage.Hash.add(key, page);
}
}
pdoPage.loadPage(href, config);
}
}
});
if (config.history) {
window.addEventListener('popstate', function (e) {
if (e.state && e.state['pdoPage']) {
pdoPage.loadPage(e.state['pdoPage'], config);
}
});
history.replaceState({pdoPage: window.location.href}, '');
}
break;
case 'scroll':
case 'button':
if (config.history) {
console.warn('Sticky pagination requires jQuery in this version');
} else {
var pagination = document.querySelector(config.pagination);
if (pagination) pagination.style.display = 'none';
}
var key = config['pageVarKey'];
if (config['mode'] == 'button') {
// Добавляем кноку
var rows = document.querySelector(config['rows']);
if (rows && config['moreTpl']) {
rows.insertAdjacentHTML('afterend', config['moreTpl']);
}
var has_results = false;
var links = document.querySelectorAll(config['link']);
for (var i = 0; i < links.length; i++) {
var href = links[i].getAttribute('href');
var match = href.match(new RegExp(key + '=(\\d+)'));
var page = !match ? 1 : match[1];
if (page > pdoPage.keys[key]) {
has_results = true;
break;
}
}
var moreBtn = document.querySelector(config['more']);
if (moreBtn && !has_results) {
moreBtn.style.display = 'none';
}
document.addEventListener('click', function(e) {
if (e.target.matches(config['more'])) {
e.preventDefault();
pdoPage.addPage(config);
}
});
} else {
// Скрол
var wrapper = document.querySelector(config['wrapper']);
window.addEventListener('scroll', function () {
if (!pdoPage.Reached && wrapper) {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var windowHeight = window.innerHeight;
var wrapperHeight = wrapper.offsetHeight;
var wrapperTop = wrapper.getBoundingClientRect().top + scrollTop;
if (scrollTop + windowHeight >= wrapperTop + wrapperHeight - 100) {
pdoPage.Reached = true;
pdoPage.addPage(config);
}
}
});
}
break;
}
};
pdoPage.addPage = function (config) {
var key = config['pageVarKey'];
var current = pdoPage.keys[key] || 1;
var links = document.querySelectorAll(config['link']);
for (var i = 0; i < links.length; i++) {
var href = links[i].getAttribute('href');
var match = href.match(new RegExp(key + '=(\\d+)'));
var page = !match ? 1 : Number(match[1]);
if (page > current) {
if (config.history) {
if (page == 1) {
pdoPage.Hash.remove(key);
} else {
pdoPage.Hash.add(key, page);
}
}
pdoPage.loadPage(href, config, 'append');
break;
}
}
};
pdoPage.loadPage = function (href, config, mode) {
var wrapper = document.querySelector(config['wrapper']);
var rows = document.querySelector(config['rows']);
var pagination = document.querySelector(config['pagination']);
var key = config['pageVarKey'];
var match = href.match(new RegExp(key + '=(\\d+)'));
var page = !match ? 1 : Number(match[1]);
if (!mode) {
mode = 'replace';
}
if (pdoPage.keys[key] == page) {
return;
}
// Блокируем если множественные запросы
if (wrapper && wrapper.classList.contains('loading')) {
return;
}
if (pdoPage.callbacks['before'] && typeof(pdoPage.callbacks['before']) == 'function') {
pdoPage.callbacks['before'].apply(this, [config]);
} else {
if (config['mode'] != 'scroll' && wrapper) {
wrapper.style.opacity = '0.3';
}
if (wrapper) wrapper.classList.add('loading');
}
var params = pdoPage.Hash.get();
for (var i in params) {
if (params.hasOwnProperty(i) && pdoPage.keys[i] && i != key) {
delete(params[i]);
}
}
params[key] = pdoPage.keys[key] = page;
params['pageId'] = config['pageId'];
params['hash'] = config['hash'];
// Формируем данные
var formData = new URLSearchParams();
for (var param in params) {
if (params.hasOwnProperty(param)) {
formData.append(param, params[param]);
}
}
fetch(config['connectorUrl'], {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest'
},
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('HTTP error! status: ' + response.status);
}
return response.text().then(text => {
if (!text || text.trim() === '') {
throw new Error('Empty response from server');
}
try {
return JSON.parse(text);
} catch (e) {
throw new Error('Invalid JSON response: ' + e.message);
}
});
})
.then(response => {
console.log('Parsed response:', response);
if (!response || typeof response !== 'object') {
throw new Error('Invalid response format');
}
if (response.success === false) {
throw new Error('Server returned error: ' + (response.message || 'Unknown error'));
}
if (pagination && response['pagination'] !== undefined) {
pagination.innerHTML = response['pagination'];
}
if (mode == 'append') {
if (rows && response['output'] !== undefined) {
rows.insertAdjacentHTML('beforeend', response['output']);
}
if (config['mode'] == 'button') {
var moreBtn = document.querySelector(config['more']);
if (moreBtn) {
if (response['pages'] == response['page']) {
moreBtn.style.display = 'none';
} else {
moreBtn.style.display = '';
}
}
} else if (config['mode'] == 'scroll') {
pdoPage.Reached = false;
}
} else {
if (rows && response['output'] !== undefined) {
rows.innerHTML = response['output'];
}
}
if (pdoPage.callbacks['after'] && typeof(pdoPage.callbacks['after']) == 'function') {
pdoPage.callbacks['after'].apply(this, [config, response]);
} else {
if (wrapper) {
wrapper.classList.remove('loading');
if (config['mode'] != 'scroll') {
wrapper.style.opacity = '1';
if (config['mode'] == 'default' && config['scrollTop'] !== false) {
var wrapperPosition = wrapper.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo(0, (wrapperPosition - 50) || 0);
}
}
}
}
pdoPage.updateTitle(config, response);
// Trigger
var event = new CustomEvent('pdopage_load', {
detail: [config, response]
});
document.dispatchEvent(event);
})
.catch(error => {
console.error('Error loading page:', error);
// Показываем если есть ошибки
if (wrapper) {
var errorMsg = document.createElement('div');
errorMsg.className = 'pdoPage-error';
errorMsg.style.cssText = 'background: #ffebee; color: #c62828; padding: 10px; margin: 10px 0; border: 1px solid #ffcdd2; border-radius: 4px;';
errorMsg.textContent = 'Ошибка загрузки страницы: ' + error.message;
if (rows) {
rows.appendChild(errorMsg);
}
wrapper.classList.remove('loading');
wrapper.style.opacity = '1';
}
// Fallback через 2 секунды
setTimeout(function() {
console.log('Fallback to regular page load:', href);
window.location.href = href;
}, 2000);
});
};
pdoPage.stickyPagination = function (config) {
console.warn('Sticky pagination requires jQuery');
};
pdoPage.updateTitle = function (config, response) {
if (typeof(pdoTitle) == 'undefined') {
return;
}
var title = document.querySelector('title');
if (!title) return;
var separator = pdoTitle.separator || ' / ';
var tpl = pdoTitle.tpl;
var newTitle = [];
var items = title.textContent.split(separator);
var pcre = new RegExp('^' + tpl.split(' ')[0] + ' ');
for (var i = 0; i < items.length; i++) {
if (i === 1 && response.page && response.page > 1) {
newTitle.push(tpl.replace('{page}', response.page).replace('{pageCount}', response.pages));
}
if (!items[i].match(pcre)) {
newTitle.push(items[i]);
}
}
title.textContent = newTitle.join(separator);
};
pdoPage.Hash = {
get: function () {
var vars = {}, hash, splitter, hashes;
if (!this.oldbrowser()) {
var pos = window.location.href.indexOf('?');
hashes = (pos != -1) ? decodeURIComponent(window.location.href.substr(pos + 1)).replace('+', ' ') : '';
splitter = '&';
} else {
hashes = decodeURIComponent(window.location.hash.substr(1)).replace('+', ' ');
splitter = '/';
}
if (hashes.length == 0) {
return vars;
} else {
hashes = hashes.split(splitter);
}
var matches, key;
for (var i in hashes) {
if (hashes.hasOwnProperty(i)) {
hash = hashes[i].split('=');
if (typeof hash[1] == 'undefined') {
vars['anchor'] = hash[0];
} else {
matches = hash[0].match(/\[(.*?|)\]$/);
if (matches) {
key = hash[0].replace(matches[0], '');
if (!vars.hasOwnProperty(key)) {
if (matches[1] == '') {
vars[key] = [];
} else {
vars[key] = {};
}
}
if (vars[key] instanceof Array) {
vars[key].push(hash[1]);
} else {
vars[key][matches[1]] = hash[1];
}
} else {
vars[hash[0]] = hash[1];
}
}
}
}
return vars;
},
set: function (vars) {
var hash = '';
for (var i in vars) {
if (vars.hasOwnProperty(i)) {
if (typeof vars[i] == 'object') {
for (var j in vars[i]) {
if (vars[i].hasOwnProperty(j)) {
if (vars[i] instanceof Array) {
hash += '&' + i + '[]=' + vars[i][j];
} else {
hash += '&' + i + '[' + j + ']=' + vars[i][j];
}
}
}
} else {
hash += '&' + i + '=' + vars[i];
}
}
}
if (!this.oldbrowser()) {
if (hash.length != 0) {
hash = '?' + hash.substr(1);
}
window.history.pushState({pdoPage: document.location.pathname + hash}, '', document.location.pathname + hash);
} else {
window.location.hash = hash.substr(1);
}
},
add: function (key, val) {
var hash = this.get();
hash[key] = val;
this.set(hash);
},
remove: function (key) {
var hash = this.get();
delete hash[key];
this.set(hash);
},
clear: function () {
this.set({});
},
oldbrowser: function () {
return !(window.history && history.pushState);
}
};
if (typeof(document.querySelector) == 'undefined') {
console.log("This browser doesn't support querySelector which is required for pdoPage.");
}Если найдете косяки в коде напишите сюдаКомментарии: 5
Плюс тебе за старания, но почему же ты не сделал публичный репозиторий для кода? Ну в целом в SendIt тоже есть пагинация и нет jQuery)))
да по хорошему нужно весь PdoTools подправить
тут писали давно что хотят обновить и тишина
Думаю заняться если Василий даст добро
Будет у меня первая такая штука
тут писали давно что хотят обновить и тишина
Думаю заняться если Василий даст добро
Будет у меня первая такая штука
Даю добро!
Правда, меня не нужно спрашивать, потому что всеми старыми дополнениями управляет сообщество уже года 4 как.
Правда, меня не нужно спрашивать, потому что всеми старыми дополнениями управляет сообщество уже года 4 как.
А как обновить его. Просто тут выложить?
На GitHub давно новых релизов не было
На GitHub давно новых релизов не было
Сделать форк нужного репозитория. Внести правки. Сделать PR в основной репозиторий.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.