PDA

View Full Version : Virtual Pagination script: jump to top next content



chechu
09-01-2017, 09:20 AM
1) Script Title: Virtual Pagination script v2.1

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex17/virtualpagination.htm

3) Describe problem: Very nice script, but when clicking on a link to the next content, when that link is placed at the bottom of the content, it would be nice if the next content is shown as from its top, and not that he next content is shown at the same height as where the link to that next content is shown. In other words: when clicking to see next content, it would be nice if that next content would be shown from its top.

If you understand it, please let me know if this is possible and how to achieve it.
Thanks.

jscheuer1
09-04-2017, 02:16 PM
OK, well there doesn't seem to be a situation like that on the demo page, so I created one by editing the markup for the first demo, adding id, height, and overflow-y to the container div:


<div id="listingpaginate" class="paginationstyle">
<a href="#" rel="previous" class="imglinks"><img src="35.gif" /></a> <select></select> <a href="#" rel="next" class="imglinks"><img src="36.gif" /></a>
</div>

<div id="scroller1" style="max-width: 450px; border: 1px dashed gray; padding: 10px; height: 300px; overflow-y: scroll;">

content paragraphs removed to save space

</div>

By giving it an explicit height less than the height of it contents and an overflow-y of scroll, it will have a scrollbar, and you can scroll it, and if you don't return it to its top and change the content, it will be somewhere other than the top when the next content appears. I added the id so I would have a way of accessing it. The paginate div already had an id. I then added code in the console, which you can add as this script as long as it comes after the markup for the pagination instance, it's holder and contents:


<script>
(function(){
var pg = document.getElementById('listingpaginate'), pgls = pg.getElementsByTagName('a'), pgselect = pg.getElementsByTagName('select')[0];
function resettop(){document.getElementById('scroller1').scrollTop = 0;}
pgls[0].addEventListener('click', resettop, false);
pgls[1].addEventListener('click', resettop, false);
pgselect.addEventListener('change', resettop, false);
})();
</script>

That way, each time a paginate link is clicked or the paginate select is changed, the content holder will scroll to the top. If you're using additional methods for loading content, additional code may be necessary, depending upon what you're doing.

If you want more help, please post a link to the page on your site that has the problematic code.

jscheuer1
09-04-2017, 02:41 PM
A different solution occurred to me for this. Instead of what I was suggesting, you could just edit the script here (a little past half way down in the code), adding the highlighted line:


// -------------------------------------------------------------------
// PRIVATE: showpage(pagenumber)- Shows a page based on parameter passed (0=page1, 1=page2 etc)
// -------------------------------------------------------------------

virtualpaginate.prototype.showpage=function(pagenumber){
var totalitems=this.pieces.length //total number of broken up divs
var showstartindex=pagenumber*this.chunksize //array index of div to start showing per pagenumber setting
var showendindex=showstartindex+this.chunksize-1 //array index of div to stop showing after per pagenumber setting
this.pieces[0].parentNode.scrollTop = 0;
for (var i=0; i<totalitems; i++){
if (i>=showstartindex && i<=showendindex)
this.pieces[i].style.display="block"
else
this.pieces[i].style.display="none"
}
if (this.persist){ //if persistence enabled
virtualpaginate.setCookie("dd_"+this.piececlass, this.currentpage)
}
if (this.cpspan.length>0){ //if <span class="paginateinfo> element is present, update it with the most current info (ie: Page 3/4)
for (var p=0; p<this.cpspan.length; p++)
this.cpspan[p].innerHTML='Page '+(this.currentpage+1)+'/'+this.pagecount
}
}

Save and use that version. That also worked for me on the demo page.

The browser cache may need to be cleared and/or the page refreshed to see changes.

chechu
09-25-2017, 09:32 AM
Thanks for your support, John.
It doesn't entirely work for me: see here (http://croatia-luxury-villa.com/dalmatia/Aindex.php).
Would there be something else that needs to be added, please?

jscheuer1
09-25-2017, 04:20 PM
Yes sure, in that setup it's the entire page which is scrolling. So instead of:


this.pieces[0].parentNode.scrollTop = 0;

You would want:


window.scrollTo(0, 0);

The (0, 0) there by the way are x, y coordinates. So if you don't want the page going all the way to the top, determine the y offset that you want and use that.

For that particular page:


window.scrollTo(0, 500);

seemed good.

You can actually set different y coordinates for different pages and/or different pagination features on the same page, still using the same script. If you need to do either of those, let me know.

chechu
09-25-2017, 05:40 PM
Thanks, John, really works well.

Just a few questions:
- is it possible to change the y coordinates into an id that can be referred to at the title of that section, so that on all devices it will be at the same height
- how can I place multiple paginations on the same page
- is it possible to have a link f.ex. to page 6 into the pagination, or will it always be the url of the page no matter what page in the pagination I'm viewing

Hopefully you can help me out with this; really appreciate it.

jscheuer1
09-25-2017, 06:52 PM
Yes, to the first. And since I see you already have jQuery on the page, it's easier. Select your anchor element and give it an id, say - paginatetop. Then change the code to:


window.scrollTo(0, $('#paginatetop').offset().top);

Which will usually work. I'm not aware of any code which would work in all cases. Things that might trip it up are margins on the HTML element (which are usually absent) or the zoom state of the browser. The first is usually small if it exists at all and if not, you could manually correct for it by adding or subtracting to the $('#paginatetop').offset().top result. If the browser zooms. usually it will take into account everything for you. Sometimes though a browser may not.

As for the second question, there are multiple paginations on the demo page, so just follow the instructions. If you need to set separate "tops", let me know.

As for the third question, this page:

http://www.dynamicdrive.com/dynamicindex17/virtualpagination_ref.htm

explains (among other things) how to call a particular pagination script's content via a URL parameter when linking to the page with the pagination script on it.

chechu
09-25-2017, 07:15 PM
Hey John,
This solution

window.scrollTo(0, $('#paginatetop').offset().top);
doesn't seem to work, as the content is all gone now: http://croatia-luxury-villa.com/dalmatia/Aindex.php
Thanks for the other input!

jscheuer1
09-25-2017, 07:40 PM
jQuery must be loaded before the pagination script. Sorry, forgot to check that. Means you have to put:


<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>

before:


<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

chechu
09-25-2017, 07:56 PM
Switched it, but still doesn't work.
And could this have something to do with it too: http://www.dynamicdrive.com/forums/showthread.php?81362-Chained-menu-not-working

jscheuer1
09-25-2017, 08:36 PM
I don't think so, though there's a small possibility that may also be a factor. What happened is that you did the opposite of what I suggested. Instead of putting:


<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>

before:


<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

You put:


<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

after the jQuery script. Unfortunately, virtualpaginate.js is needed before that. it's needed before:


<script type="text/javascript">
var gallery=new virtualpaginate({
piececlass: "virtualpage",
piececontainer: 'div',
pieces_per_page: 1,
defaultpage: 0,
wraparound: false,
persist: true
})
gallery.buildpagination(["gallerypaginate", "gallerypaginate2"])
</script>

I suppose you could move that last part to the very end now. But I think it might work better if you just did it like I suggested in the first place.

Yep, that's it. And once it's working, I think position() will work better than offset() - must have something to do with how the page is laid out. Not sure how cross device that will be (seems to be OK in limited emulation though).

chechu
09-25-2017, 08:51 PM
I tried placing this in the footer:

<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>
<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

<script type="text/javascript">
(function(){
function loader(){
initListGroup('chainedmenu', document.listmenu0.firstlevel, document.listmenu0.secondlevel, document.listmenu0.thirdlevel, 'savestate');
}
if (window.addEventListener)
window.addEventListener('load', loader, false);
else if (window.attachEvent)
window.attachEvent('onload', loader);
})();
</script>

Doesn't work.
And I also tried placing the follwing in the header:

<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>
and this in the footer:

<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

<script type="text/javascript">
(function(){
function loader(){
initListGroup('chainedmenu', document.listmenu0.firstlevel, document.listmenu0.secondlevel, document.listmenu0.thirdlevel, 'savestate');
}
if (window.addEventListener)
window.addEventListener('load', loader, false);
else if (window.attachEvent)
window.attachEvent('onload', loader);
})();
</script>
And also doesn't work.
Quit confused now. And the chained menu is breaking my head ...

jscheuer1
09-25-2017, 09:03 PM
I might not be the best person to explain this to you. I did get it working here using the console. I just moved:


<script type="text/javascript">
var gallery=new virtualpaginate({
piececlass: "virtualpage",
piececontainer: 'div',
pieces_per_page: 1,
defaultpage: 0,
wraparound: false,
persist: true
})
gallery.buildpagination(["gallerypaginate", "gallerypaginate2"])
</script>

to the end and changed (in the virtualpaginate.js script):

offset()

to

position()

in that part we were already editing.

But it seems whatever I say, you find a way to do something different. Partly my problem I'm sure. Sorry I wasn't able to help you more.

chechu
09-25-2017, 09:22 PM
Sorry, I copied wrong.
So first I placed this all in the footer:

<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>
<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>
<script type="text/javascript">
(function(){
function loader(){
initListGroup('chainedmenu', document.listmenu0.firstlevel, document.listmenu0.secondlevel, document.listmenu0.thirdlevel, 'savestate');
}
if (window.addEventListener)
window.addEventListener('load', loader, false);
else if (window.attachEvent)
window.attachEvent('onload', loader);
})();
</script>
But that didn't work.

And then I separated them, placing this in the header:

<script src="https://croatia-luxury-villa.com/js/jquery.min.js"></script>
and this in the footer:

<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>

<script type="text/javascript">
(function(){
function loader(){
initListGroup('chainedmenu', document.listmenu0.firstlevel, document.listmenu0.secondlevel, document.listmenu0.thirdlevel, 'savestate');
}
if (window.addEventListener)
window.addEventListener('load', loader, false);
else if (window.attachEvent)
window.attachEvent('onload', loader);
})();
</script>

So I presume I placed the right code before the other code, as you explained.
And I changed now offset into position.
But it still doesn't work, so please advice.

jscheuer1
09-26-2017, 12:04 AM
I never mentioned anything about the loader function. Where did that come from?

Anyways, if you carefully go over all that I've already told you, everything you need is there. The only thing I haven't yet covered is how to have two or more "tops" if you need them. But for now we're just trying to get one top working with one pagination instance, and as I say, that's all there.

The only other thing I can think of to do is to setup a demo for you. Assuming your page is still up and hasn't changed too much since I had it working in the console, when I have some time, I'll do that.

Oh, and there's always the possibility that another participant in the forums will chime in. That's happened before. Sometimes that just confuses things further. But it has happened that another user understands what I'm saying and can explain it to the original person (you in this case).

Still a good chance we will get this settled.

jscheuer1
09-26-2017, 12:18 AM
OK, looks good, only problem I see now is that the:


<script src="http://croatia-luxury-villa.com/js/virtualpaginate.js"></script>


is no longer on the page.

Assuming things are as they were when I did this, here's a working demo:

demo removed because problem solved and content likely proprietary

chechu
09-26-2017, 07:09 AM
Pff, I copied the wrong stuff again, must be the jetlag.
Sorry, John, and thanks, indeed it all works well now. But the chained menu is still not working, and that I noticed whilst I was working on this pagination script with you.
Any idea what could have happened there? Because it works when opening the link in a new tab, but then you'll see that the url of the page changes into this (ex.):

URL?firstlevel=&secondlevel=&thirdlevel=URL
My aim is to have it opening in the same tab.
Thanks.

jscheuer1
09-26-2017, 02:24 PM
Glad that's working. And I answered your question about the chained menu in your thread that you started about that:

http://www.dynamicdrive.com/forums/showthread.php?81362-Chained-menu-not-working&p=322386#post322386

chechu
09-26-2017, 07:25 PM
Thanks, John.

chechu
09-29-2017, 08:39 AM
Hey John,

Still an issue, it seems. I added the code to another page, but instead of going back to #paginatetop, it goes back to the top of the page when clicking on the next content.
See here: https://croatia-luxury-villa.com/test.php

And what if I add another pagination to the same page? Then the #paginatetop cannot be used multiple times, it seems, because it is in the javascript.

Also, is it possible to add a feature so that the scrolling to the top of the content goes with a smooth transition?

Thanks!

jscheuer1
09-29-2017, 04:22 PM
I'm not really sure where else on that page you would want it to scroll to, perhaps my browser is showing it differently. But, if it's not scrolling to where you want it to, you should try to scroll to a different element. This element can be an otherwise unseen span that you just place wherever seems best. If that doesn't fix that, we can talk about using an adjustment to wherever the code takes it. I would add that we are already lucky in a way this has worked at all because the pages we've done this with are laid out and/or scripted in an odd fashion such that they don't scroll in the normal manner.

As for animating and using a separate top for each instance -

OK, our little line inside the script gets more complex. It is currently:


window.scrollTo(0, $('#paginatetop').position().top);

Now let's make it like so:


if(this.pagetop){$('html, body').animate({scrollTop: $(this.pagetop).position().top});}

And we have to add something to the main function (again, in the main script, this time near the top):


function virtualpaginate(config){ //config: {piececlass:, piececontainer:, pieces_per_page:, defaultpage:, wraparound:, persist}
this.pagetop = config.pagetop
this.piececlass=config.piececlass
var elementType=(typeof config.piececontainer=="undefined")? "div" : config.piececontainer //The type of element used to divide up content into pieces. Defaults to "div"
this.pieces=virtualpaginate.collectElementbyClass(config.piececlass, elementType) //get total number of divs matching class name
//Set this.chunksize: 1 if "chunksize" param is undefined, "chunksize" if it's less than total pieces available, or simply total pieces avail (show all)
this.chunksize=(typeof config.pieces_per_page=="undefined")? 1 : (config.pieces_per_page>0 && config.pieces_per_page<this.pieces.length)? config.pieces_per_page : this.pieces.length
this.pagecount=Math.ceil(this.pieces.length/this.chunksize) //calculate number of "pages" needed to show the divs
this.wraparound=config.wraparound || false
this.paginatediv=[], this.flatviewlinks=[], this.cpspan=[], this.selectmenu=[], this.prevlinks=[], this.nextlinks=[]
this.persist=config.persist
var persistedpage=virtualpaginate.getCookie("dd_"+this.piececlass) || 0
var urlselectedpage=virtualpaginate.urlparamselect(this.piececlass) //returns null or index from: mypage.htm?piececlass=index
this.currentpage=(typeof urlselectedpage=="number")? urlselectedpage : ((this.persist)? persistedpage : config.defaultpage)
this.currentpage=(this.currentpage<this.pagecount)? parseInt(this.currentpage) : 0 //ensure currentpage is within range of available pages
this.showpage(this.currentpage) //Show selected page
}

Then when you initialize the script, you declare the selector for the pagination top:


<script type="text/javascript">
var gallery=new virtualpaginate({
piececlass: "virtualpage",
piececontainer: 'div',
pagetop: '#paginatetop',
pieces_per_page: 1,
defaultpage: 0,
wraparound: false,
persist: true
})
gallery.buildpagination(["gallerypaginate", "gallerypaginate2"])