Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

paging like google, small problem 2

Status
Not open for further replies.

tyutghf

Technical User
Apr 12, 2008
258
GB
I have noticed a problem on my paging results that I made to look like google.

Here is what is meant to happen: 10 results either side of the page being viewed are meant to display, so say I am on page 30, I see 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40.
When on single digit pages it is meant to show as many as it can to the left and ten to the right so page 4 sho0uld show 1 2 3 4 5 6 7 8 9 10 11 12 13

The results page shows 14 records at a time on each page.

However I am getting a problem:

The first set of results (page 1) show the first 14 results,
clicking to page 2 shows results 28 - 42
clicking back to page 1 shows 14-28

So there are two issues, the results are missing the second set of results and skipping straight to what should be on page 3, but when I go back to page 1 they miss the first 14 and start at 14.

I have starred at this so much that I can`t see the issue, can someone see an obvious problem?

Code:
<div class='prevnextbuttons'>

<%
if Request.QueryString("page") = "" then
intCurrentPage = 1 
else
intCurrentPage = CInt(Request.QueryString("page"))
end if
intPageCount = allrecords/14 - 1
intPageSplit = 10

'next and previous buttons
        if Request.QueryString("page") = "" then intnextpage = 2 else intnextpage = Request.QueryString("page") + 1
        intprevpage = Request.QueryString("page") - 1
								
								


'previous button
if intprevpage >= 1 then
response.write "<a href='?page=" & intprevpage & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>&lt;&lt; Previous</a> "
end if


' -- Calculate Beginning Page Numbers --
intBegEnd = intCurrentPage - 1
If intCurrentPage > intPageSplit Then
	intBegStart = intCurrentPage - intPageSplit
ElseIf intPageCount < intPageSplit OR intCurrentPage <= intPageSplit Then
	intBegStart = 1 
End If


' -- Calculate Ending Page Numbers --
intEndStart = intCurrentPage + 1
If intCurrentPage <= (intPageCount - intPageSplit) Then
	intEndEnd = intCurrentPage + intPageSplit
ElseIf intCurrentPage > (intPageCount - intPageSplit) Then
	intEndEnd = intPageCount
End If


' -- Create Page Numbers --
For x = intBegStart To intBegEnd
	response.write "<a href='?page=" & x & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>" & x & "</a> | "
Next
response.write "<b> Page " & intCurrentPage & "</b>"
For x = intEndStart To intEndEnd
	response.write " | <a href='?page=" & x & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>" & x & "</a>"
Next
%>

<%
'next button
if intnextpage <= intEndEnd then
response.write " <a href='?page=" & intnextpage & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>Next &gt;&gt;</a>"
end if
%>

</div>

Thanks for any help
 
something like this?
Code:
<%
	if request.querystring("page") = "" then
		intCurrentPage = 1
	else
		intCurrentPage = cint(request.querystring("page"))
	end if
	
	allRecords = 500
	intNumberOfRecordsPerPage = 14
	intPageCount = (allRecords/intNumberOfRecordsPerPage)
	
	' if the page count contains a decimal, then increment the page count by one
	if inStr(intPageCount,".") > 1 then intPageCount = intPageCount + 1
	
	' remove the decimal
	intPageCount = formatNumber(intPageCount,0)
	
	intPageSplit = 10
%>

<%
	' prev page
	if intCurrentPage > 1 then 
		response.write "<a href='?page=" & intCurrentPage - 1 & "'>prev</a> . "
	end if
%>
<%
	' page links
	pageLinksStart = 1
	pageLinksEnd = intPageSplit
	
	if intCurrentPage - intPageSplit > 1 then pageLinksStart = intCurrentPage - intPageSplit
	if intCurrentPage + intPageSplit < intPageCount and intCurrentPage >= 10 then 
		pageLinksEnd = intCurrentPage + intPageSplit 
	end if
	
	for ndx = pageLinksStart to pageLinksEnd
		if ndx = intCurrentPage then
			response.write  "<strong>" & ndx & "</strong> . "
		else
			response.write  "<a href='?page=" & ndx & "'>" & ndx & "</a> . "		
		end if
	next
%>
<%
	' next page
	if intCurrentPage < cint(intPageCount) then 
		response.write "<a href='?page=" & intCurrentPage + 1 & "'>next</a>"
	end if
%>

TIP: trying googling the answer before posting, you'll find that more times than not someone else somewhere has had the same request and posted an answer online.
----
I have recently been semi-converted to ensuring all my code (well most of it) works in both javascript and non-javascript enabled browsers
 
Thanks for the reply, the first pages seem to work ok now thank you.

The pages however keep going, there are 57 pages of results but the pages go on infinately counting at the bottom. Also, the next buttons disappears on page 37, 20 pages short of the 57 there are in total.

I set allRecords to equal the number of results grabbed out of the database using count. This keeps the next button there but it stays displayed even after page 57.

allRecords is coming out at 809 total records
intPageCount = (allrecords/intNumberOfRecordsPerPage)
which should come out at 57 but it is coming out at 59 when I response.write it

Code:
<%
    if request.querystring("page") = "" then
        intCurrentPage = 1
    else
        intCurrentPage = cint(request.querystring("page"))
    end if
    
    intNumberOfRecordsPerPage = 14
    intPageCount = (allrecords/intNumberOfRecordsPerPage)
    
    ' if the page count contains a decimal, then increment the page count by one
    if inStr(intPageCount,".") > 1 then intPageCount = intPageCount + 1
    
    ' remove the decimal
    intPageCount = formatNumber(intPageCount,0)
    
    intPageSplit = 10
%>

<%
    ' prev page
    if intCurrentPage > 1 then
        response.write "<a href='?page=" & intCurrentPage - 1 & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>&lt;&lt; Previous</a> | "
    end if
%>
<%
    ' page links
    pageLinksStart = 1
    pageLinksEnd = intPageSplit
    
    if intCurrentPage - intPageSplit > 1 then pageLinksStart = intCurrentPage - intPageSplit
    if intCurrentPage + intPageSplit < intPageCount and intCurrentPage >= 10 then
        pageLinksEnd = intCurrentPage + intPageSplit
    end if
    
    for ndx = pageLinksStart to pageLinksEnd
        if ndx = intCurrentPage then
            response.write  "<strong>Page " & ndx & "</strong> | "
        else
            response.write  "<a href='?page=" & ndx & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>" & ndx & "</a> | "        
        end if
    next
%>
<%
    ' next page
    if intCurrentPage < cint(intPageCount) then
        response.write "<a href='?page=" & intCurrentPage + 1 & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>Next &gt;&gt;</a>"
    end if
%>
 
There were some rounding issues and a few other conditional issues..try this version

Code:
<%
    if request.querystring("page") = "" then
        intCurrentPage = 1
    else
        intCurrentPage = cint(request.querystring("page"))
    end if
    allRecords = 15
    intNumberOfRecordsPerPage = 14
    intPageCount = (allrecords/intNumberOfRecordsPerPage)
    ' if the page count contains a decimal, then increment the page count by one
    if inStr(intPageCount,".") > 1 then 
	raPageCount = split(intPageCount,".")
	intPageCount = raPageCount(0) + 1
	erase raPageCount
    end if
    
    ' remove the decimal
    intPageCount = formatNumber(intPageCount,0)
    
    intPageSplit = 10
%>

<%
    ' prev page
    if intCurrentPage > 1 then
        response.write "<a href='?page=" & intCurrentPage - 1 & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>&lt;&lt; Previous</a> | "
    end if
%>
<%
    ' page links
    pageLinksStart = 1
    pageLinksEnd = 10
    
	if cint(pageLinksEnd) > cint(intPageCount) then pageLinksEnd = intPageCount
	
    if intCurrentPage - intPageSplit > 1 then pageLinksStart = intCurrentPage - intPageSplit
    
    if intCurrentPage + intPageSplit < intPageCount and intCurrentPage >= 10 then 
	pageLinksEnd = intCurrentPage + intPageSplit
	if cint(pageLinksEnd) > cint(intPageCount) then pageLinksEnd = intPageCount
    end if
    
    for ndx = pageLinksStart to pageLinksEnd
        if ndx = intCurrentPage then
            response.write  "<strong>Page " & ndx & "</strong> | "
        else
            response.write  "<a href='?page=" & ndx & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>" & ndx & "</a> | "        
        end if
    next
%>
<%
    ' next page
    if pageLinksEnd < cint(intPageCount) then
        response.write "<a href='?page=" & intCurrentPage + 1 & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>Next &gt;&gt;</a>"
    end if
%>

TIP: trying googling the answer before posting, you'll find that more times than not someone else somewhere has had the same request and posted an answer online.
----
I have recently been semi-converted to ensuring all my code (well most of it) works in both javascript and non-javascript enabled browsers
 
oh mannn, you are having the same problem I did in that the first results are showing great so I get 1-14, press next and I get 28-42, go back to page 1 and see 14-28.

Also, the next button disappears on page 48, 10 pages before the total of 58.

Thank you for your ongoing help with this, this is a big learning curve for me and looking through your code I can see what you are doing, many thanks
 
When you say:

oh mannn, you are having the same problem I did in that the first results are showing great so I get 1-14, press next and I get 28-42, go back to page 1 and see 14-28.

Are you talking about the records? That really has nothing to do with the code above, that's in your query (i'm assuming you getting your results from a db table and they are sorted in some manner (i.e record_id)

It will involve more work as you'll need to grab x number of results and keep track with a pointer of where you left off and where you began..can you provide your db schemea + the queries you are using (doesn't need to match exactly, but the basic structure would be needed).



TIP: trying googling the answer before posting, you'll find that more times than not someone else somewhere has had the same request and posted an answer online.
----
I have recently been semi-converted to ensuring all my code (well most of it) works in both javascript and non-javascript enabled browsers
 
The actual SQL is quite huge as the search facility has many options so I stripped it all down to the bare minimum to try and figure out this problem.

Here is the barebones

Code:
<%

SQL = "SELECT userid, name FROM users order by name"
Set rs = Server.CreateObject("ADODB.Recordset")

'paging!!
recordsonpage = 14
' count all records
allrecords = 0
set rsCount = Objconn.Execute(SQL)
do until rsCount.EOF
  allrecords = allrecords + 1
  rsCount.movenext
loop				

' if offset is zero then the first page will be loaded
page = request.querystring("page")*14
if page = 0 OR page = "" then
  requestrecords = 0
else
  requestrecords = requestrecords + page
end if

set rs = Objconn.Execute(SQL)

hiddenrecords = requestrecords
do until hiddenrecords = 0 OR rs.EOF
  hiddenrecords = hiddenrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop				


if RS.EOF then									
response.write "No results matched your search, try adjusting your search criterea and search again."
else
									
									
' prints records in the table
showrecords = recordsonpage
recordcounter = requestrecords
do until showrecords = 0 OR rs.EOF
recordcounter = recordcounter + 1		

%>

<div class='resultdisplay'>
<%=rs("name")%>
</div>

<%

showrecords = showrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop
								
								
         end if  
 

				rs.close: set rs = nothing 
    objConn.close: set objConn = nothing
%> 									

<div class='prevnextlinks'>

<%
    if request.querystring("page") = "" then
        intCurrentPage = 1
    else
        intCurrentPage = cint(request.querystring("page"))
    end if
    'allRecords = 15
    intNumberOfRecordsPerPage = 14
    intPageCount = (allrecords/intNumberOfRecordsPerPage)
    ' if the page count contains a decimal, then increment the page count by one
    if inStr(intPageCount,".") > 1 then
    raPageCount = split(intPageCount,".")
    intPageCount = raPageCount(0) + 1
    erase raPageCount
    end if
    
    ' remove the decimal
    intPageCount = formatNumber(intPageCount,0)
    
    intPageSplit = 10
%>

<%
    ' prev page
    if intCurrentPage > 1 then
        response.write "<a href='?page=" & intCurrentPage - 1 & "&genre="&strgenre&"&profiletype="&strprofiletype&"&location="&strLocation&"'>&lt;&lt; Previous</a> | "
    end if
%>
<%
    ' page links
    pageLinksStart = 1
    pageLinksEnd = 10
    
    if cint(pageLinksEnd) > cint(intPageCount) then pageLinksEnd = intPageCount
    
    if intCurrentPage - intPageSplit > 1 then pageLinksStart = intCurrentPage - intPageSplit
    
    if intCurrentPage + intPageSplit < intPageCount and intCurrentPage >= 10 then
    pageLinksEnd = intCurrentPage + intPageSplit
    if cint(pageLinksEnd) > cint(intPageCount) then pageLinksEnd = intPageCount
    end if
    
    for ndx = pageLinksStart to pageLinksEnd
        if ndx = intCurrentPage then
            response.write  "<strong>Page " & ndx & "</strong> | "
        else
            response.write  "<a href='?page=" & ndx & "'>" & ndx & "</a> | "        
        end if
    next
%>
<%
    ' next page
    if pageLinksEnd < cint(intPageCount) then
        response.write "<a href='?page=" & intCurrentPage + 1 & "'>Next &gt;&gt;</a>"
    end if
%>

</div>

Gonna be a long night :eek:(
 
aha, it is the requestrecords that is causing the issue

Code:
page = request.querystring("page")*14
if page = 0 OR page = "" then
  requestrecords = 0
else
  requestrecords = requestrecords + page
end if

When the first page is loaded there is no page querystring so the results start from 0, when I go to page two requestrecords was starting from 28 (2*14).

To fix the issue at the start of the results I changed

requestrecords = requestrecords + page
to
requestrecords = (requestrecords + page) - recordsonpage

Now onto the problem with the next button disappearing on page 47...

 
it's only 10:30 where I am - I won't have time to look at this until later this afternoon, I know i can help figure it out, but it will require a bit of a re-write...

Just by looking at it, there are a few things you should consider:

1. Don't count the records everytime the page is loaded, you should count them once and then pass the total as a querystring value - will get rid of a lot of overhead.

2. You should be opening your record set as an object

Code:
set rs = server.createObject("ADODB.Recordset")
rs.open sqlCommand,conn

^ that will allow you to use a simple command like rs.recordcount to return the total number of records.

3. By opening it as an object, you can then moveTo a record, so you can retrive all the records from the db, and check the page number (say page 2) muliply it by the number of records per page (say 14) and move to that first record - (page - 1 * 14).

4. Your SQL query can be modified to only return the number of records you need - so if you are on page 2, you know you don't need anything past record 28, so use a "select top 28 userid, name from myTable order by name"

^ summarize to get you going, let me know how it turns out and I can try and help some more...

Code:
rpp = 14 ' records per page
ttlRec = request.querystring("ttlRec") ' total records
page = request.querystring("page")

if page = "" then page = 1
' if you are on page...you want to start at record....
' 1...0
' 2...14
' 3...28
firstRecord = (page - 1) * rpp

' if you are on page...you want to get up to record number....
' 1...14
' 2...28
' 3...42
lastRecord = page * rpp

sqlCmd = "select top " & lastRecord & " user_id, name from myTable order by name asc"
set rs = server.createObject("ADODB.Recordset")

' if you don't already have the total records, count them here
if ttlRec = "" then ttlRec = rs.recordCount

' move to the first record you want to display
rs.moveTo(firstRecord)

' display all the records after the first one
' you only have up to how many you want, so you can go to EOF
do while not rs.eof
 response.write name & "<br />"
	if not rs.eof then rs.movenext
loop

' close and dispose of the recordset
rs.close
set rs = nothing

TIP: trying googling the answer before posting, you'll find that more times than not someone else somewhere has had the same request and posted an answer online.
----
I have recently been semi-converted to ensuring all my code (well most of it) works in both javascript and non-javascript enabled browsers
 
vic made a very important point, open the recordset as an object between the use of pagesize, pagecount, and cursor location sould be all you need with the exception of developing out your method of handling the math and layout of how you want total pages, how many page jump links you want to use, etc. also with the use of pagesize etc, you can use these values in your loop statements and so forth, check the faqs on pagination.

I'm also going to run through the logics i use in making this type pagination display, especially since you're having problems with number shifts, and mis-displays, this is not to insult you or your abilities, just as a reference point for you to fix this and help in future endeavors (it's ALWAYS something small we miss ourselves, and who proof-reads code for you...Dam book authors get perks like proof-readers and research dept)

usually i'll go as easy as i can on the math so at 4AM i can still make heads or tails of it. example:

you want to display 11 pagelinks (5 either side of current page for continuity, 2 of the total being next and previous page, making 4 active pagelinks per side)

we;ll start with the initial display,
<prev>1-4(links),|5|,6-9(links)<next> (of howevermany)

you could use some inordinate math to evaluate the difference, the offset etc, i'm lazy i use a couple variables and a buncha conditionals .. so lets say there's 59 pages, we'll apply the logics to both page 2 of 59 and page 57 of 59 (totalpages) and some random page in between

note: pagesize irrelevant, you can add an option to change number of records displayed and use a little math to recalculate the page number based on cursorlocation, just dont forget to recalc total pages as well.

lets get all the variables out of the way: (of course dump my commentary)
Code:
currentpage [:)]
totalpages [:D]
span (this is the arbitrary display format number, best to use an odd number in our case it's _9_ because prev/next dont count in the display)
spread (this is that 4 number mentioned in the display)

startpos
endpos (these are for the for/next in display and derived shortly)

[green]'beginning of pageset setup[/green]
if currentpage < span-spread then
  startpos = 1
  endpos = span
[green]'end of pageset setup[/green]
elseif currentpage > totalpages-(span-spread) then
  startpos = totalpages-span
  endpos = totalpages
[green]'anywhere in between, there's enough room for +/- 4 links[/green]
else
  startpos = currentpage-spread
  endpos = currentpage+spread
end if
[green]
' the vbcrlf's are only for your benefit when viewing page source[/green]

if currentpage > startpos then
  Response.write "prev&nbsp;" [green]' null prev display[/green]
else
  response.write "<a href="searchwhatever.asp?page=" & currentpage-1 & "'>Prev&nbsp;</a>" & vbcrlf
end if
for i=startpos to endpos
  if i=currentpage then
    response.write i & vbcrlf 
  else
    response.write "<a href='searchwatever.asp?page=" & i & "'>" & i & "</a>" & vbcrlf
  end if
next
if currentpage < endpos then
  Response.write "next&nbsp;" [green]' null next display[/green]
else
  response.write "<a href="searchwhatever.asp?page=" & currentpage+1 & "'>next&nbsp;</a>" & vbcrlf
end if
now using the math for page 2 and page 57 of 59

if currentpage < span-spread then (2/True) (57/False)
startpos = 1
endpos = span 2(9)
[green]'end of pageset setup[/green]
elseif currentpage > totalpages-(span-spread) then (2/False) (57/True)
startpos = totalpages-span 57(50)
endpos = totalpages 57(59)
[green]'anywhere in between, there's enough room for +/- 4 links[/green]
else (24/true)
startpos = currentpage-spread 24(20)
endpos = currentpage+spread 24(28)
end if


hopefully that helps

[thumbsup2]DreX
aKa - Robert
if all else fails, light it on fire and do the happy dance!
" I always think outside the 'box', because I'm never in the 'loop' " - DreX 2005
 
i kinda brushed on it, but as vic said using the recordset as an object and using it's methods your paging becomes alot easier to mess with, and alot less data needs to be handled, basically you just need to querystring across the pagenumber, and you can carry the query and pagesize in session values, when they make a new search, this is of course replaced, as for it automatically displaying the search results when hitting the search page, if there's no page value in the querystring, you dont execute the recordset pull.

nonetheless, this is a very nicely done faq on pagination:
[thumbsup2]DreX
aKa - Robert
if all else fails, light it on fire and do the happy dance!
" I always think outside the 'box', because I'm never in the 'loop' " - DreX 2005
 
Thanks folks, my dad has been rushed into hospital so won`t be able to look at this for a few days but hope to get a chance over the weekend.
 
bum deal tyutghf, i hope all goes well and he's ok.

[thumbsup2]DreX
aKa - Robert
if all else fails, light it on fire and do the happy dance!
" I always think outside the 'box', because I'm never in the 'loop' " - DreX 2005
 
Thanks for the help vic and drex, struggling to get my head around your suggestions at the mo with all the other stuff going on at the mo. Will pick this back up in a week or so and hopefully try to grasp what you are suggesting.
 
Oh man I have spent hours and hours on this and can`t seem to make it work. I have looked at other paging examples and then recreated myself but this system to make it work like google is eluding me.
 
well we can take it steps at a time if you'd like getting the google-like display isn't the easiest thing to do, paging records aint a big deal, but forcing a format to the page results gets complicated.

[thumbsup2]DreX
aKa - Robert
if all else fails, light it on fire and do the happy dance!
" I always think outside the 'box', because I'm never in the 'loop' " - DreX 2005
 
I have done it! I completely cleared my head and rewrote the links portion again from scratch using the help given above. Thanks for all of the help folks, it is VERY much appreciated.
 
no worries, glad to hear it's working and hope the write through was helpful.

[thumbsup2]DreX
aKa - Robert
if all else fails, light it on fire and do the happy dance!
" I always think outside the 'box', because I'm never in the 'loop' " - DreX 2005
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top