diff --git a/themes/bootstrap5/js/channels.js b/themes/bootstrap5/js/channels.js index 649428f63f66..6769bf0f17fa 100644 --- a/themes/bootstrap5/js/channels.js +++ b/themes/bootstrap5/js/channels.js @@ -174,7 +174,7 @@ VuFind.register("channels", function Channels() { return false; } - // Disable and relabel button + // disable more paging disableLoadMoreBtn(btn); // Reveal hidden items @@ -182,28 +182,34 @@ VuFind.register("channels", function Channels() { const pageSize = Number(targetChannel.dataset.pageSize); const hiddenItems = targetChannel.querySelectorAll(".hidden-batch-item"); + // If we're waiting for more records + if (hiddenItems.length === 0) { + return; + } + // Reveal hidden items (limit to pageSize) - hiddenItems.forEach((item, index) => { - if (index < pageSize) { - item.classList.remove("hidden-batch-item"); - clampLines(item.querySelector(".channel-item-title")); - } - }); + for (let i = 0; i < pageSize && i < hiddenItems.length; i++) { + hiddenItems[i].classList.remove("hidden-batch-item"); + clampLines(hiddenItems[i].querySelector(".channel-item-title")); + } - // Out of records - if (hiddenItems.length > 0 && hiddenItems.length < Number(targetChannel.dataset.rowSize)) { - hideLoadMoreBtn(btn); + // enable more paging + enableLoadMoreBtn(btn); + + // do we have enough hidden items to add another page? + const remainingHiddenItems = hiddenItems.length - pageSize; + if (remainingHiddenItems > pageSize) { return; } - // How many more records do we need? - const neededCount = pageSize - hiddenItems.length; - if (neededCount <= 0) { - enableLoadMoreBtn(btn); - return; // skip loading more records + // we don't have any more records to load + if (targetChannel.dataset.endReached) { + hideLoadMoreBtn(btn); + return; } // AJAX load more records + // should fire when we have only have one page of items left const url = new URL(decodeURIComponent(btn.dataset.href), location.origin); fetch(url.toString() + "&layout=lightbox") .then((res) => res.text()) @@ -216,26 +222,36 @@ VuFind.register("channels", function Channels() { ? firstChannel.querySelectorAll(".channel-item") : []; + // mark that we've loaded all records + if (records.length < pageSize) { + targetChannel.dataset.endReached = true; + } + + // no new records to add + if (records.length === 0) { + return; + } + + // add new records (hidden) const targetList = targetChannel.querySelector(".channel-list"); + let index = Number(targetChannel.dataset.loaded); + targetChannel.dataset.loaded = index + records.length; for (let i = 0; i < records.length; i++) { const record = records[i]; + record.dataset.index = index++; + record.classList.remove("hidden"); - if (i >= neededCount) { - record.classList.add("hidden-batch-item"); - } + record.classList.add("hidden-batch-item"); targetList.append(record); + clampLines(record.querySelector(".channel-item-title")); } - // Hide button - if (records.length < Number(targetChannel.dataset.batchSize)) { - hideLoadMoreBtn(btn); - } else { - enableLoadMoreBtn(btn); - } + }).then(() => { + enableLoadMoreBtn(btn); }); - // Set button to next, next page + // Set button to next page url.searchParams.set("page", Number(url.searchParams.get("page")) + 1); btn.setAttribute("data-href", url.toString()); } @@ -280,7 +296,7 @@ VuFind.register("channels", function Channels() { .setAttribute("href", `${VuFind.path}/Channels/Record?${expandParams}`); const prevBtn = content.querySelector(".ql-prev-item-btn"); - if (record.previousElementSibling) { + if (Number(record.dataset.index) > 0) { prevBtn.classList.remove("disabled"); prevBtn.removeAttribute("disabled"); } else { @@ -345,6 +361,7 @@ VuFind.register("channels", function Channels() { for (const channelEl of document.querySelectorAll(".channel")) { // Disable the load more button is there are less items than the batchSize const allItems = channelEl.querySelectorAll(".channel-item"); + channelEl.dataset.loaded = allItems.length; if (allItems.length < Number(channelEl.dataset.rowSize)) { hideLoadMoreBtn(channelEl.querySelector(".channel-load-more-btn")); } @@ -403,7 +420,7 @@ VuFind.register("channels", function Channels() { group.dataset.recordSource, group.dataset.recordId ); - if (record.previousElementSibling) { + if (Number(record.dataset.index) > 0) { quickLook(record.previousElementSibling, group.dataset.channelId); event.preventDefault(); return false; diff --git a/themes/bootstrap5/templates/channels/channelList.phtml b/themes/bootstrap5/templates/channels/channelList.phtml index 3f9ba1413929..35bc7b6be6fc 100644 --- a/themes/bootstrap5/templates/channels/channelList.phtml +++ b/themes/bootstrap5/templates/channels/channelList.phtml @@ -95,13 +95,15 @@ $url = empty($item['routeDetails']) ? $this->recordLinker()->getUrl("{$item['source']}|{$item['id']}") : $this->url($item['routeDetails']['route'], $item['routeDetails']['params']); + $channelItemAttrs = [ + 'class' => 'channel-item' . ($index < $channel['config']['pageSize'] ? '' : ' hidden-batch-item'), + 'data-channel-id' => $channelID, + 'data-index' => $index, + 'data-record-id' => $item['id'], + 'data-record-source' => $item['source'], + ]; ?> -
  • + htmlAttributes($channelItemAttrs) ?>>