wiki:Search_Pagination
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 2 (modified by fredlin, 13 years ago) (diff)

--

Search Pagination

This article is not written done yet

This article is showing you how to make a "Search Pagination" with SQLObject and kid.

Expect result

We assume we have 35 entries, and make each page shows 10 entries.

Expect result is: "| 1 | 2 | 3 | 4 |"

Advanced Expect result is: "Prev | 1 | 2 | 3 | 4 | Next",

"Prev/Next?" only shows if this action is possible. (first page shows "| 1 | 2 | 3 | 4 | Next", last page shows "Prev | 1 | 2 | 3 | 4 |")

Solution

Basic:

  • query data from database
  • select a number of entries as a set
  • offset to next set
  • add url link

Advanced:

  • compare "start not equal to zero" if we need to show the "prev" button.
  • compare "set_end" and "set_size" to decide if we need to show the "Next" button.
  • add url link

Detail

Basic:

controller.py expose function is:

@expose(html=".templates.pagesearch")
def index(self, start = 0):
    a = TableEntry.select(TableEntry.q.fieldA == True, orderBy='fieldB')
    return dict(context = a, start = int(start)*10, offset = 10,)

"a = TableEntry?.select...." is SQLObject select expression, it will return a generator type.

then we pass it in a return dict key, which named "context".

The "start" param is used to indicate the "page" sets.

The "offset" param in the return dict is used to control the "size of display list".

kid template pagesearch.kid

We tempt to keep controll logic and presentation seperate. So we do all "view" stuff in template.

Now we have some calculation work,

Since we have 35 entries, and make each page shows 10 entries.

We got total "4" pages.

The expression is :

>>> (35/10)+1
4

So now we programmer see a function with 2 params can be used in template, "35" as "query_size" and "10" as "offset".

>>>query_size = 35
>>>offset = 10
>>>(query_size/offset)+1
4

Yes it works correctly.

We can read each entry from generator by using "for" loop.

To get subsets of the context generator type, we use list-like function to draw target sets. "context[start:end]"

ex: for the first 10 records:

context[0:10]

and for the next 10:

context[10:20]

and so on.

Let's put those python expressions into real kid template

<?python
    query_size = context.count()+1
    end = start*10 +offset
?>
<ul>
  <li py:for="post in context[start:end]">[${post.fieldA}] ${post.fieldB}: ${post.fieldC}</li>
</ul>

<div>
 | <span py:for = " i in xrange((query_size/offset)+1)"> <a href="/?start=${i}">${i+1}</a> | </span>
</div>

kid template's "py:for" is equal to python "for" loop. "query_size" is equal to "context.count()", which "context.count()" will return total queried entry numbers.

and we get "offset" param from "index" method's return dict.

"|" is used only for pretty.

Advanced:

... To Be Continued ...