Skip to content

Commit

Permalink
Merge pull request #151 from aropan/show_more_table
Browse files Browse the repository at this point in the history
Add show_more_table
  • Loading branch information
shtalinberg authored Jun 29, 2023
2 parents 39fcc74 + b9f22bd commit c0885a0
Show file tree
Hide file tree
Showing 22 changed files with 252 additions and 22 deletions.
10 changes: 5 additions & 5 deletions HACKING
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ Run the tests::

$ make test

The command above also runs all the available integration tests. They use
Selenium and require Firefox to be installed. To avoid executing integration
tests, define the environment variable SKIP_SELENIUM, e.g.::
The command above also runs all tests except the available integration. They use
Selenium and require Firefox to be installed. To include executing integration
tests, define the environment variable USE_SELENIUM, e.g.::

$ make test SKIP_SELENIUM=1
$ make test USE_SELENIUM=1

Integration tests are excluded by default when using Python 3. The test suite
requires Python >= 2.6.6.
Expand All @@ -45,7 +45,7 @@ Run the tests and lint/pep8 checks::

Again, to exclude integration tests::

$ make check SKIP_SELENIUM=1
$ make check USE_SELENIUM=1

Debugging
~~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ help:
@echo 'E.g. to run tests and linter under Python 3:'
@echo ' - make check PY3=1'
@echo -e '\nWhen testing the application, define the env var'
@echo 'SKIP_SELENIUM to exclude integration tests, e.g.:'
@echo ' - make check SKIP_SELENIUM=1'
@echo 'USE_SELENIUM to include integration tests, e.g.:'
@echo ' - make check USE_SELENIUM=1'
@echo -e '\nWhen running integration tests, by default all graphical'
@echo 'operations are performed in memory where possible. However,'
@echo 'it is possible to run tests using a visible browser instance'
Expand Down
10 changes: 5 additions & 5 deletions doc/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ Run the tests::

$ make test

The command above also runs all the available integration tests. They use
Selenium and require Firefox to be installed. To avoid executing integration
tests, define the environment variable SKIP_SELENIUM, e.g.::
The command above also runs all tests except the available integration. They use
Selenium and require Firefox to be installed. To include executing integration
tests, define the environment variable USE_SELENIUM, e.g.::

$ make test SKIP_SELENIUM=1
$ make test USE_SELENIUM=1

Integration tests are excluded by default when using Python 3. The test suite
requires Python >= 3.8.x.
Expand All @@ -60,7 +60,7 @@ Run the tests and lint/pep8 checks::

Again, to exclude integration tests::

$ make check SKIP_SELENIUM=1
$ make check USE_SELENIUM=1

Debugging
~~~~~~~~~
Expand Down
43 changes: 43 additions & 0 deletions doc/templatetags_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,49 @@ You can override the loading text too:

Must be called after `paginate`_ or `lazy_paginate`_.

.. _templatetags-show-more-table:

show_more_table
~~~~~~~~~~~~~~~

Same as the `show_more`_, but for table pagination. Usage:

.. code-block:: html+django

{% show_more_table %}

If use table in a :doc:`twitter_pagination`:

.. code-block:: html+django

<table>
{% include page_template %}
</table>

then page template:

.. code-block:: html+django

{% load el_pagination_tags %}

{% paginate 5 objects %}
{% for object in objects %}
<tr>
<td>
{{ object.title }}
</td>
</tr>
{% endfor %}
{% show_more_table "More results" %}

For :doc:`digg_pagination` use instead `show_more_table` in page template:

.. code-block:: html+django

<tr>
<td>{% show_pages %}</td>
</td>

.. _templatetags-get-pages:

get_pages
Expand Down
2 changes: 1 addition & 1 deletion doc/twitter_pagination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ just use the *paginateOnScrollChunkSize* option:
Specifying where the content will be inserted
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you are paginating a table, you may want to include the *show_more* link
If you are paginating a table, you can use :ref:`templatetags-show-more-table` or you may want to include the *show_more* link
after the table itself, but the loaded content should be placed inside the
table.

Expand Down
19 changes: 18 additions & 1 deletion el_pagination/paginators.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ def _get_num_pages(self):
num_pages = property(_get_num_pages)


class LazyPaginatorCustomPage(Page):
"""Handle different number of items on the first page."""

def start_index(self):
"""Return the 1-based index of the first item on this page."""
paginator = self.paginator
if self.number == 1:
return 1
return (
(self.number - 2) * paginator.per_page + paginator.first_page + 1)

def end_index(self):
"""Return the 1-based index of the last item on this page."""
paginator = self.paginator
return (self.number - 1) * paginator.per_page + paginator.first_page


class LazyPaginator(BasePaginator):
"""Implement lazy pagination."""

Expand Down Expand Up @@ -107,7 +124,7 @@ def page(self, number):
else:
# This is the last page.
self._num_pages = number
return CustomPage(objects, number, self)
return LazyPaginatorCustomPage(objects, number, self)

def _get_count(self):
raise NotImplementedError
Expand Down
10 changes: 10 additions & 0 deletions el_pagination/templates/el_pagination/show_more_table.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% load i18n %}
{% if querystring %}
<tr class="endless_container">
<td colspan="100%">
<a class="endless_more{% if class_name %} {{ class_name }}{% endif %}" href="{{ path }}{{ querystring }}"
data-el-querystring-key="{{ querystring_key }}">{% if label %}{{ label|safe }}{% else %}{% trans "more" %}{% endif %}</a>
<span class="endless_loading" style="display: none;">{{ loading|safe }}</span>
</td>
</tr>
{% endif %}
18 changes: 18 additions & 0 deletions el_pagination/templatetags/el_pagination_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,24 @@ def show_more(context, label=None, loading=settings.LOADING, class_name=None):
return {}


@register.inclusion_tag('el_pagination/show_more_table.html', takes_context=True)
def show_more_table(context, label=None, loading=settings.LOADING):

"""Show the link to get the next page in a Twitter-like pagination in a
template for table.
Usage::
{% show_more_table %}
Alternatively you can override the label passed to the default template::
{% show_more_table "even more" %}
You can override the loading text too::
{% show_more_table "even more" "working" %}
Must be called after ``{% paginate objects %}``.
"""
# This template tag could raise a PaginationError: you have to call
# *paginate* or *lazy_paginate* before including the showmore template.
return show_more(context, label, loading)


@register.tag
def get_pages(parser, token):
"""Add to context the list of page links.
Expand Down
4 changes: 3 additions & 1 deletion el_pagination/tests/integration/test_chunks.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ def test_subsequent_page(self):
def test_chunks(self):
# Ensure new items are not loaded on scroll if the chunk is complete.
self.get()
for i in range(5):
while len(self.get_current_elements('item')) < 20:
self.scroll_down()
self.wait_ajax()
self.scroll_down()
self.wait_ajax()
self.assertElements('object', range(1, 16))
self.assertElements('item', range(1, 21))
6 changes: 6 additions & 0 deletions el_pagination/tests/integration/test_digg.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,9 @@ def test_no_next_link_in_last_page(self):
# Ensure there is no forward link on the last page.
self.get(page=10)
self.asserLinksEqual(0, self.NEXT)


class DiggPaginationTableTest(DiggPaginationTest):

view_name = 'digg-table'
selector = 'tr.{0} td > h4'
6 changes: 6 additions & 0 deletions el_pagination/tests/integration/test_onscroll.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,9 @@ def test_scrolling_last_page(self):
self.get(page=5)
with self.assertNewElements('object', range(41, 51)):
self.scroll_down()


class OnScrollPaginationTableTest(OnScrollPaginationTest):

view_name = 'onscroll-table'
selector = 'tr.{0} td > h4'
6 changes: 6 additions & 0 deletions el_pagination/tests/integration/test_twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ def test_no_more_link_in_last_page(self):
# Ensure there is no more link on the last page.
self.get(page=10)
self.asserLinksEqual(0, self.MORE)


class TwitterPaginationTableTest(TwitterPaginationTest):

view_name = 'twitter-table'
selector = 'tr.{0} td > h4'
22 changes: 17 additions & 5 deletions el_pagination/tests/templatetags/test_el_pagination_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,44 +357,56 @@ def test_num_queries_starting_from_another_page(self):
@skip_if_old_etree
class ShowMoreTest(EtreeTemplateTagsTestMixin, TestCase):

tagname = 'show_more'

def render(self, request, contents, **kwargs):
text = string.Template(contents).substitute(tagname=self.tagname)
return super(ShowMoreTest, self).render(request, text, **kwargs)

def test_first_page_next_url(self):
# Ensure the link to the next page is correctly generated
# in the first page.
template = '{% paginate objects %}{% show_more %}'
template = '{% paginate objects %}{% $tagname %}'
tree = self.render(self.request(), template)
link = tree.find('.//a[@class="endless_more"]')
expected = '/?{0}={1}'.format(settings.PAGE_LABEL, 2)
self.assertEqual(expected, link.attrib['href'])

def test_page_next_url(self):
# Ensure the link to the next page is correctly generated.
template = '{% paginate objects %}{% show_more %}'
template = '{% paginate objects %}{% $tagname %}'
tree = self.render(self.request(page=3), template)
link = tree.find('.//a[@class="endless_more"]')
expected = '/?{0}={1}'.format(settings.PAGE_LABEL, 4)
self.assertEqual(expected, link.attrib['href'])

def test_last_page(self):
# Ensure the output for the last page is empty.
template = '{% paginate 40 objects %}{% show_more %}'
template = '{% paginate 40 objects %}{% $tagname %}'
tree = self.render(self.request(page=2), template)
self.assertIsNone(tree)

def test_customized_label(self):
# Ensure the link to the next page is correctly generated.
template = '{% paginate objects %}{% show_more "again and again" %}'
template = '{% paginate objects %}{% $tagname "again and again" %}'
tree = self.render(self.request(), template)
link = tree.find('.//a[@class="endless_more"]')
self.assertEqual('again and again', link.text)

def test_customized_loading(self):
# Ensure the link to the next page is correctly generated.
template = '{% paginate objects %}{% show_more "more" "working" %}'
template = '{% paginate objects %}{% $tagname "more" "working" %}'
tree = self.render(self.request(), template)
loading = tree.find('.//*[@class="endless_loading"]')
self.assertEqual('working', loading.text)


@skip_if_old_etree
class ShowMoreTableTest(ShowMoreTest):

tagname = 'show_more_table'


class GetPagesTest(TemplateTagsTestMixin, TestCase):

def test_page_list(self):
Expand Down
3 changes: 3 additions & 0 deletions tests/project/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
('multiple', 'Multiple'),
('callbacks', 'Callbacks'),
('chunks', 'On scroll/chunks'),
('digg-table', 'Digg-style table'),
('twitter-table', 'Twitter-style table'),
('onscroll-table', 'On scroll table'),
)


Expand Down
9 changes: 9 additions & 0 deletions tests/project/static/pagination.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Customized css for the pagination elements. */

.pagination div,
.pagination td,
.endless_container {
display: inline-block;
*display: inline;
Expand All @@ -16,6 +17,7 @@
}

.pagination div > a,
.pagination td > a,
.pagination span,
.endless_container a {
float: left;
Expand All @@ -27,13 +29,16 @@
}

.pagination div > a:hover,
.pagination td > a:hover,
.pagination .endless_page_current,
.endless_container a:hover {
background-color: #eeeeee;
}

.pagination div > a:first-child,
.pagination div > span:first-child,
.pagination td > a:first-child,
.pagination td > span:first-child,
.endless_container a {
border-left-width: 1px;
-webkit-border-radius: 3px 0 0 3px;
Expand All @@ -50,3 +55,7 @@
width: inherit;
text-decoration: none;
}

td {
padding: 20px;
}
14 changes: 14 additions & 0 deletions tests/project/templates/digg/table/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends "base.html" %}

{% block content %}
<table class="endless_page_template span12">
{% include page_template %}
</table>
{% endblock %}

{% block js %}
{{ block.super }}
<script>
$.endlessPaginate();
</script>
{% endblock %}
14 changes: 14 additions & 0 deletions tests/project/templates/digg/table/page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% load el_pagination_tags %}

{% paginate 5 objects %}
{% for object in objects %}
<tr class="well object">
<td>
<h4>{{ object.title }}</h4>
{{ object.contents }}
</td>
</tr>
{% endfor %}
<tr class="pagination pagination-centered">
<td>{% show_pages %}</td>
</td>
14 changes: 14 additions & 0 deletions tests/project/templates/onscroll/table/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends "base.html" %}

{% block content %}
<table class="span12">
{% include page_template %}
</table>
{% endblock %}

{% block js %}
{{ block.super }}
<script>
$.endlessPaginate({paginateOnScroll: true});
</script>
{% endblock %}
Loading

0 comments on commit c0885a0

Please sign in to comment.