Infinite scrolling

Tips submitted by PHPMaker users
Post Reply
Adam
User
Posts: 480

Infinite scrolling

Post by Adam »

It seems that this feature is reasonably popular so here's my quick and easy (just 2 steps) solution that seems to work quite nicely...

Step 1... Add this single line to the relevant Client Scripts > Table-Specific > List Page > Startup Script:

infiniteScroll();

Step 2... Add this code to Client Scripts > Global > Pages with header/footer > Global Code:

function infiniteScroll(delay = 1000, previewCheck = true) { // Refresh period ... 1000 = 1 second
$('form[name="ew-pager-form"]').hide();

if ($('#autoscroll').length == 0)
$('<span id="autoscroll" data-page="1"></span>').insertAfter('table.ew-table');

$.fn.inViewport = function() {
var win = $(window);
var viewport = { top: win.scrollTop(), left: win.scrollLeft() };
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};

manageScroll(delay, previewCheck);

function manageScroll(delay, previewCheck) {
if (!((previewCheck && $('.ew-preview-row-btn.icon-collapse').length > 0) || $('.ew-detail-pages').length > 0 || $('.modal.show').length > 0))
{
if ($('#autoscroll').length > 0) {
if ($('#autoscroll').inViewport()) {
page = parseInt($('#autoscroll').attr('data-page'));
pages = parseInt($('input.form-control[name=pageno]').attr('data-pagecount'));
records = parseInt($('input.form-control[name=pageno]').attr('data-pagesize'));
if (page < pages)
{
url = location.href + '?';
url = url.substring(0, url.indexOf('?')) + '?pageno=1&recperpage=' + (page * records);
$('#autoscroll').attr('data-page', String(page + 1));
$('.ew-preview-row-btn.icon-collapse').trigger('click');
$('table.ew-table > tbody').load(url + ' table.ew-table > tbody tr', function(response, status, xhr) {
if (status == 'success') {
$(this).find('tr:even').removeClass('ew-table-alt-row').addClass('ew-table-row');
$(this).find('tr:odd').removeClass('ew-table-row').addClass('ew-table-alt-row');
$('.ew-preview-row-btn').click(ew.showDetails);
$('div.ew-preview [data-toggle="tab"]').on('show.bs.tab', ew.tabShow);
$('div.popover').hide();
ew.initTooltips();
}
});
url = url.substring(0, url.indexOf('?')) + '?pageno=1&recperpage=' + records;
$.get(url);
}
}
}
}
setTimeout(manageScroll, delay, delay, previewCheck);
}
}

...and then regenerate at least the relevant list page and the userfn.js files.

I suggest that you set the page size to 5 - that seems to be a good number of records to add each time, and the default delay of 1000ms also seems to work quite well, but feel free to experiment.

Be aware that the top and/or bottom paging controls will be removed from view to avoid interfering with the infinite scroll functionality.

As with my list refreshing code, the default is to abort if a preview panel or model dialog is open, but those checks can be overridden as required.

Enjoy!


sticcino
User
Posts: 1043

Post by sticcino »

cool,

  • cursor progress icon stays on screen and the page progress icon are always displayed
  • as soon as page is loaded the 5 recs display, then 10, then 15, then 20 then 25..... without even "scrolling down", this should sit at the 5 until the cursor moves to the bottom of the page, testing on a contacts form which has 2000 records

can you add a floating "arrow" to go back out 5-10 rows/page up ?


mobhar
User
Posts: 11660

Post by mobhar »

If we have 11 or 12 records in the current table, the first 5 records and the second 5 records are successfully displayed in the List page after scrolling down to the bottom of page. Unfortunately, the last 1 or 2 records will not displayed.


Adam
User
Posts: 480

Post by Adam »

I'm not quite sure how that could occur... if you have 11 or 12 records then there would be 3 pages, so "if (page < pages)" would still be true.

You can try moving "$('#autoscroll').attr('data-page', String(page + 1));" into the "if (status == 'success') {" block and see if that helps.


mobhar
User
Posts: 11660

Post by mobhar »

Adam wrote:

so "if (page < pages)" would still be true.

I don't think so. That code should be:

if (page <= pages)

Adam wrote:

You can try moving "$('#autoscroll').attr('data-page', String(page + 1));" into the "if (status == 'success') {" block and see if that helps.

Yep, that did the trick, too.

So here is the latest updated version (I added comment using BEFORE word to see the previous condition):

function infiniteScroll(delay = 1000, previewCheck = true) { // Refresh period ... 1000 = 1 second
	$('form[name="ew-pager-form"]').hide();

	if ($('#autoscroll').length == 0)
		$('<span id="autoscroll" data-page="1"></span>').insertAfter('table.ew-table');

	$.fn.inViewport = function() {
		var win = $(window);
		var viewport = { top: win.scrollTop(), left: win.scrollLeft() };
		viewport.right = viewport.left + win.width();
		viewport.bottom = viewport.top + win.height();
		var bounds = this.offset();
		bounds.right = bounds.left + this.outerWidth();
		bounds.bottom = bounds.top + this.outerHeight();
		return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
	};

	manageScroll(delay, previewCheck);

	function manageScroll(delay, previewCheck) {
		if (!((previewCheck && $('.ew-preview-row-btn.icon-collapse').length > 0) || $('.ew-detail-pages').length > 0 || $('.modal.show').length > 0))
		{
			if ($('#autoscroll').length > 0) {
				if ($('#autoscroll').inViewport()) {
					page = parseInt($('#autoscroll').attr('data-page'));
					pages = parseInt($('input.form-control[name=pageno]').attr('data-pagecount'));
					records = parseInt($('input.form-control[name=pageno]').attr('data-pagesize'));
					if (page <= pages)  // BEFORE: page < pages
					{
						url = location.href + '?';
						url = url.substring(0, url.indexOf('?')) + '?pageno=1&recperpage=' + (page * records);
						$('.ew-preview-row-btn.icon-collapse').trigger('click');
						$('table.ew-table > tbody').load(url + ' table.ew-table > tbody tr', function(response, status, xhr) {
						if (status == 'success') {
							$('#autoscroll').attr('data-page', String(page + 1));  // BEFORE: it is located outside/above this block
							$(this).find('tr:even').removeClass('ew-table-alt-row').addClass('ew-table-row');
							$(this).find('tr:odd').removeClass('ew-table-row').addClass('ew-table-alt-row');
							$('.ew-preview-row-btn').click(ew.showDetails);
							$('div.ew-preview [data-toggle="tab"]').on('show.bs.tab', ew.tabShow);
							$('div.popover').hide();
							ew.initTooltips();
						}
						});
						url = url.substring(0, url.indexOf('?')) + '?pageno=1&recperpage=' + records;
						$.get(url);
					}
				}
			}
		}
		setTimeout(manageScroll, delay, delay, previewCheck);
	}
}

Bishu
User
Posts: 427

Post by Bishu »

Wow! it is a very nice option. I love it

here when I scroll down a long record and try to move to the Top it takes a long time.

I hope it will be nice to have a small floating button "TOP"
so that we can move directly to "TOP" easily.


Bishu
User
Posts: 427

Post by Bishu »

It is working perfect on Normal List Page.

But When I try to use in custom templates List Page all the data are hide and only the table border are showing.

I have created a simple table format and "table.ew-table > tbody tr" is in the table.

My custom table is as follows.

<table class="table ew-table">
	<thead>
		<tr class="ew-table-header">
			<th>{{{mobile}}}</th>
		</tr>
	 </thead>
	 <tbody> 
		<tr {{{row_attrs}}}>
			<td>{{{mobile}}}</td>
		</tr>
 	</tbody>
</table>

Can anyone please guide me to run this "Infinite Scrolling" while using List Custom Templates?

I am unable to debug the issue.


mobhar
User
Posts: 11660

Post by mobhar »

I don't think it will work properly in Custom Templates, since its behavior is difference with the normal List page.


bui
User
Posts: 277

Post by bui »

Is there any update for Version 2022


Adam
User
Posts: 480

Post by Adam »

Not yet, but you're welcome to give it a go - the concept was fairly basic.


bui
User
Posts: 277

Post by bui »

Adam wrote:

Not yet, but you're welcome to give it a go - the concept was fairly basic.

Thanks. This Infinite scrolling is very useful.
It will be better if it works for the Custom Template also.


Adam
User
Posts: 480

Post by Adam »

As long as there's a defined element that can be replaced by the Aax call then the concept will work for any page


mobhar
User
Posts: 11660

Post by mobhar »

bui wrote:

Is there any update for Version 2022

I've just tested my customization code above in v2022, and it works properly in the normal List page (without using Custom Templates).


bui
User
Posts: 277

Post by bui »

Is there any alternate way to do with the Custom Templates?


mdfaisalpapa
User
Posts: 84

Post by mdfaisalpapa »

mobhar wrote:

I've just tested my customization code above in v2022, and it works properly in the normal List page (without using Custom Templates).

Tried in v2022.7 the page loads initially with records but the records get vanished.


mobhar
User
Posts: 11660

Post by mobhar »

Press F12 and see whether any Javascript error message in Console section.


mdfaisalpapa
User
Posts: 84

Post by mdfaisalpapa »

No error message in F12.

my page is a master/detail page .

records from master and detail are visible for a second and gets hidden.

only the table header and the add button is visible


mobhar
User
Posts: 11660

Post by mobhar »

It seems it only works in single List page (not in Master/Detail List page).


mdfaisalpapa
User
Posts: 84

Post by mdfaisalpapa »

changing the line
$('<span id="autoscroll" data-page="1"></span>').insertAfter('table.ew-table');
to
$('<span id="autoscroll" data-page="1"></span>').insertAfter('table.ew-table:last');

makes it work in both the normal page and master/detail page


Post Reply