diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4335bf2..37a0a84 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ CHANGELOG =========== +v. 2.2.0 +-------- + + * Add new classes: + * ``ColumnShiftTableBootstrap4Responsive`` - only for django-tables2 >= 2.5.0 + * ``ColumnShiftTableBootstrap5Responsive`` - only for django-tables2 >= 2.5.3 + + Classes able to use responsive tables with Bootstrap v4 and v5 + Author: @mpibpc-mroose + v. 2.1.1 -------- diff --git a/README.rst b/README.rst index 7efe571..d1bbff4 100644 --- a/README.rst +++ b/README.rst @@ -33,8 +33,10 @@ Using JQuery, Bootstrap3 or Bootstrap4 or Bootstrap5 and Django >=1.9. * for bootstrap2 - ColumnShiftTableBootstrap2, * for bootstrap3 - ColumnShiftTableBootstrap3, - * for bootstrap4 - ColumnShiftTableBootstrap4, - * for bootstrap5 - ColumnShiftTableBootstrap5, + * for bootstrap4 - ColumnShiftTableBootstrap4 + * for bootstrap4 in responsive mode - ColumnShiftTableBootstrap4Responsive (only for django-tables2 >= 2.5) + * for bootstrap5 - ColumnShiftTableBootstrap5 + * for bootstrap5 in responsive mode - ColumnShiftTableBootstrap5Responsive (only for django-tables2 >= 2.5.3) **Tested by tox with:** @@ -218,11 +220,16 @@ Bootstrap4 : If you use Bootstrap v4 in your project then table class has to inherit from `ColumnShiftTableBootstrap4` imported from `django_tables2_column_shifter.tables`. +Alternatively if you want to use `table-responsive` your table class has to inherit from +ColumnShiftTableBootstrap4Responsive (only for django-tables2 >= 2.5). + Bootstrap5: -------------------------------------- If you use Bootstrap v5 in your project then table class has to inherit from `ColumnShiftTableBootstrap5` imported from `django_tables2_column_shifter.tables`. +Alternatively if you want to use `table-responsive` your table class has to inherit from +ColumnShiftTableBootstrap5Responsive (only for django-tables2 >= 2.5.3). Warnings: diff --git a/django_tables2_column_shifter/__init__.py b/django_tables2_column_shifter/__init__.py index c878191..243016b 100644 --- a/django_tables2_column_shifter/__init__.py +++ b/django_tables2_column_shifter/__init__.py @@ -1,2 +1,2 @@ -VERSION = (2, 1, 1) +VERSION = (2, 2, 0) __version__ = ".".join(str(i) for i in VERSION) diff --git a/django_tables2_column_shifter/tables.py b/django_tables2_column_shifter/tables.py index b21ec86..20f3180 100644 --- a/django_tables2_column_shifter/tables.py +++ b/django_tables2_column_shifter/tables.py @@ -1,8 +1,9 @@ import django_tables2 as tables +dt_version = tuple(map(int, tables.__version__.split(".")[:3])) -class ColumnShiftTable(tables.Table): +class ColumnShiftTable(tables.Table): # If button for shifting columns is visible shift_table_column = True @@ -89,9 +90,47 @@ class ColumnShiftTableBootstrap4(ColumnShiftTable): shifter_template = "django_tables2_column_shifter/bootstrap4.html" +class ColumnShiftTableBootstrap4Responsive(ColumnShiftTable): + """ + Table class compatible with Bootstrap 4 and using "table-responsive" css class. + """ + shifter_template = "django_tables2_column_shifter/bootstrap4-responsive.html" + + def __init__(self, *args, **kwargs): + if dt_version < (2, 5): + raise AssertionError( + "ColumnShiftTableBootstrap4Responsive require django-tables2 >= 2.5 " + "your current version is {}".format(tables.__version__) + ) + super(ColumnShiftTableBootstrap4Responsive, self).__init__(*args, **kwargs) + + class ColumnShiftTableBootstrap5(ColumnShiftTable): """ Table class compatible with bootstrap 5 """ dropdown_button_css = "btn btn-light btn-sm" shifter_template = "django_tables2_column_shifter/bootstrap5.html" + + def __init__(self, *args, **kwargs): + if dt_version < (2, 5): + raise AssertionError( + "ColumnShiftTableBootstrap5 require django-tables2 >= 2.5 " + "your current version is {}".format(tables.__version__) + ) + super(ColumnShiftTableBootstrap5, self).__init__(*args, **kwargs) + + +class ColumnShiftTableBootstrap5Responsive(ColumnShiftTableBootstrap5): + """ + Table class compatible with Bootstrap 5 and using "table-responsive" css class. + """ + shifter_template = "django_tables2_column_shifter/bootstrap5-responsive.html" + + def __init__(self, *args, **kwargs): + if dt_version < (2, 5, 3): + raise AssertionError( + "ColumnShiftTableBootstrap5Responsive require django-tables2 >= 2.5.3 " + "your current version is {}".format(tables.__version__) + ) + super(ColumnShiftTableBootstrap5Responsive, self).__init__(*args, **kwargs) diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap4_table_block.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap4_table_block.html new file mode 100644 index 0000000..2f6e502 --- /dev/null +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap4_table_block.html @@ -0,0 +1,80 @@ +{% load trans from i18n %} +{% load static %} + + + + + +
+ + +
{# End btn-group#} + + {# Loader default is show #} +
+ loader + {% trans "Table content is loading..."%} +
{# End loader #} + diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap5_table_block.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap5_table_block.html new file mode 100644 index 0000000..47a3f7c --- /dev/null +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/_partials/bootstrap5_table_block.html @@ -0,0 +1,79 @@ +{% load trans from i18n %} +{% load static %} + +
+ + +
{# End btn-group#} + + {# Loader default is show #} +
+ loader + {% trans "Table content is loading..."%} +
{# End loader #} diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4-responsive.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4-responsive.html new file mode 100644 index 0000000..6b620d3 --- /dev/null +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4-responsive.html @@ -0,0 +1,17 @@ +{% extends "django_tables2/bootstrap4-responsive.html" %} + +{% block table %} +{% if table.shift_table_column %} +
+ {% include 'django_tables2_column_shifter/_partials/bootstrap4_table_block.html' %} + + {# Wrapper default is hide #} + {# End table-wrapper #} +
{# End column-shifter-container #} +{% else %} + {{ block.super }} +{% endif %} +{% endblock table %} diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4.html index ac4faa4..1f7de81 100644 --- a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4.html +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap4.html @@ -1,95 +1,17 @@ {% extends "django_tables2/bootstrap4.html" %} -{% load trans from i18n %} -{% load static %} {% block table %} - {% if table.shift_table_column %} -
+ {% include 'django_tables2_column_shifter/_partials/bootstrap4_table_block.html' %} -
- - -
{# End btn-group#} - - {# Loader default is show #} -
- loader - {% trans "Table content is loading..."%} -
{# End loader #} - - {# Wrapper degault is hide #} + {# Wrapper default is hide #} {# End table-wrapper #} - -
{# End column-shifter-container #} + {# End column-shifter-container #} {% else %} {{ block.super }} {% endif %} - {% endblock table %} diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5-responsive.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5-responsive.html new file mode 100644 index 0000000..148b8e0 --- /dev/null +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5-responsive.html @@ -0,0 +1,17 @@ +{% extends "django_tables2/bootstrap5-responsive.html" %} + +{% block table %} +{% if table.shift_table_column %} +
+ {% include 'django_tables2_column_shifter/_partials/bootstrap5_table_block.html' %} + + {# Wrapper default is hide #} + {# End table-wrapper #} +
{# End column-shifter-container #} +{% else %} + {{ block.super }} +{% endif %} +{% endblock table %} diff --git a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5.html b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5.html index a65f961..38720d4 100644 --- a/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5.html +++ b/django_tables2_column_shifter/templates/django_tables2_column_shifter/bootstrap5.html @@ -1,99 +1,17 @@ -{% extends "django_tables2/bootstrap4.html" %} -{% load trans from i18n %} -{% load static %} +{% extends "django_tables2/bootstrap5.html" %} {% block table %} - {% if table.shift_table_column %} -
+ {% include 'django_tables2_column_shifter/_partials/bootstrap5_table_block.html' %} -
- - -
{# End btn-group#} - - {# Loader default is show #} -
- loader - {% trans "Table content is loading..."%} -
{# End loader #} - - {# Wrapper degault is hide #} + {# Wrapper default is hide #} {# End table-wrapper #} - -
{# End column-shifter-container #} + {# End column-shifter-container #} {% else %} {{ block.super }} {% endif %} - {% endblock table %} diff --git a/django_tables2_column_shifter/tests/test_base.py b/django_tables2_column_shifter/tests/test_base.py index f23177f..19dd937 100644 --- a/django_tables2_column_shifter/tests/test_base.py +++ b/django_tables2_column_shifter/tests/test_base.py @@ -9,10 +9,13 @@ from django_tables2_column_shifter.tests.models import Author from django_tables2_column_shifter.tables import ( + dt_version, ColumnShiftTableBootstrap2, ColumnShiftTableBootstrap3, ColumnShiftTableBootstrap4, + ColumnShiftTableBootstrap4Responsive, ColumnShiftTableBootstrap5, + ColumnShiftTableBootstrap5Responsive ) if tuple(map(int, django.__version__.split(".")[:2])) >= (1, 10): @@ -22,40 +25,51 @@ class DjangoTables2ColumnShifterTest(TestCase): - CASE = [ { 'bootstrap_version': 'bootstrap2', - 'min_dt_version': (1, 0), - 'max_dt_version': (2, 0), + 'min_dt_version': (1, 0, 0), + 'max_dt_version': (2, 0, 0), 'template_name': 'django_tables2_column_shifter/bootstrap2.html', 'table_clsss': ColumnShiftTableBootstrap2, }, { 'bootstrap_version': 'bootstrap3', - 'min_dt_version': (1, 0), - 'max_dt_version': (2, 0), + 'min_dt_version': (1, 0, 0), + 'max_dt_version': (2, 0, 0), 'template_name': 'django_tables2_column_shifter/bootstrap3.html', 'table_clsss': ColumnShiftTableBootstrap3, }, { 'bootstrap_version': 'bootstrap4', - 'min_dt_version': (2, 0), + 'min_dt_version': (2, 0, 0), 'max_dt_version': None, 'template_name': 'django_tables2_column_shifter/bootstrap4.html', 'table_clsss': ColumnShiftTableBootstrap4, }, + { + 'bootstrap_version': 'bootstrap4responsive', + 'min_dt_version': (2, 5, 0), + 'max_dt_version': None, + 'template_name': 'django_tables2_column_shifter/bootstrap4-responsive.html', + 'table_clsss': ColumnShiftTableBootstrap4Responsive, + }, { 'bootstrap_version': 'bootstrap5', - 'min_dt_version': (2, 0), + 'min_dt_version': (2, 5, 0), 'max_dt_version': None, 'template_name': 'django_tables2_column_shifter/bootstrap5.html', 'table_clsss': ColumnShiftTableBootstrap5, }, + { + 'bootstrap_version': 'bootstrap5responsive', + 'min_dt_version': (2, 5, 3), + 'max_dt_version': None, + 'template_name': 'django_tables2_column_shifter/bootstrap5-responsive.html', + 'table_clsss': ColumnShiftTableBootstrap5Responsive, + }, ] - dt_version = tuple(map(int, tables.__version__.split(".")[:2])) - def setUp(self): # Add authors to database Author.objects.create(first_name='Bradley', last_name='Ayers', age=21) @@ -69,8 +83,8 @@ def setUp(self): def test_CASE_status(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -79,8 +93,8 @@ def test_CASE_status(self): def test_general_html_content(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -92,8 +106,8 @@ def test_general_html_content(self): def test_container_ids(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -104,8 +118,8 @@ def test_container_ids(self): def test_tables_containers_count(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -114,8 +128,8 @@ def test_tables_containers_count(self): def test_buttons_count(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -124,8 +138,8 @@ def test_buttons_count(self): def test_btn_on_status_count(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -134,8 +148,8 @@ def test_btn_on_status_count(self): def test_btn_off_status_count(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -144,8 +158,8 @@ def test_btn_off_status_count(self): def test_is_pagination(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue response = self.client.get(reverse(case['bootstrap_version'])) @@ -155,8 +169,8 @@ def test_is_pagination(self): def test_tables_template(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue @@ -201,8 +215,8 @@ def test_column_excluded(self): for case in self.CASE: if ( - (case['min_dt_version'] and case['min_dt_version'] > self.dt_version) or - (case['max_dt_version'] and case['max_dt_version'] < self.dt_version) + (case['min_dt_version'] and case['min_dt_version'] > dt_version) or + (case['max_dt_version'] and case['max_dt_version'] < dt_version) ): continue diff --git a/django_tables2_column_shifter/tests/urls.py b/django_tables2_column_shifter/tests/urls.py index 4932f0c..782da0d 100644 --- a/django_tables2_column_shifter/tests/urls.py +++ b/django_tables2_column_shifter/tests/urls.py @@ -1,6 +1,13 @@ import django -from .views import Bootstrap2, Bootstrap3, Bootstrap4, Bootstrap5 +from .views import ( + Bootstrap2, + Bootstrap3, + Bootstrap4, + Bootstrap4Responsive, + Bootstrap5, + Bootstrap5Responsive, +) dj_version = tuple(map(int, django.__version__.split(".")[:2])) @@ -15,4 +22,14 @@ url(r'^bootstrap3/$', Bootstrap3.as_view(), name="bootstrap3"), url(r'^bootstrap4/$', Bootstrap4.as_view(), name="bootstrap4"), url(r'^bootstrap5/$', Bootstrap5.as_view(), name="bootstrap5"), + url( + r'^bootstrap4responsive/$', + Bootstrap4Responsive.as_view(), + name="bootstrap4responsive", + ), + url( + r'^bootstrap5responsive/$', + Bootstrap5Responsive.as_view(), + name="bootstrap5responsive", + ), ] diff --git a/django_tables2_column_shifter/tests/views.py b/django_tables2_column_shifter/tests/views.py index 6561f0b..022892d 100644 --- a/django_tables2_column_shifter/tests/views.py +++ b/django_tables2_column_shifter/tests/views.py @@ -5,7 +5,9 @@ ColumnShiftTableBootstrap2, ColumnShiftTableBootstrap3, ColumnShiftTableBootstrap4, + ColumnShiftTableBootstrap4Responsive, ColumnShiftTableBootstrap5, + ColumnShiftTableBootstrap5Responsive, ) from .models import Author, Book @@ -15,7 +17,7 @@ class BootstrapDefault(TemplateView): template_name = "django_tables2_column_shifter_tests/index.html" author_table_class = None # should be override - book_table_class = None # should be override + book_table_class = None # should be override def get_context_data(self, **kwargs): context = super(BootstrapDefault, self).get_context_data(**kwargs) @@ -55,6 +57,24 @@ class Bootstrap4(BootstrapDefault): book_table_class = get_book_table_class(ColumnShiftTableBootstrap4) +class Bootstrap4Responsive(BootstrapDefault): + author_table_class = get_author_table_class( + ColumnShiftTableBootstrap4Responsive, + ) + book_table_class = get_book_table_class( + ColumnShiftTableBootstrap4Responsive, + ) + + class Bootstrap5(BootstrapDefault): author_table_class = get_author_table_class(ColumnShiftTableBootstrap5) book_table_class = get_book_table_class(ColumnShiftTableBootstrap5) + + +class Bootstrap5Responsive(BootstrapDefault): + author_table_class = get_author_table_class( + ColumnShiftTableBootstrap5Responsive, + ) + book_table_class = get_book_table_class( + ColumnShiftTableBootstrap5Responsive + ) diff --git a/testproject/testproject/templates/base_site.html b/testproject/testproject/templates/base_site.html index 91d6e65..6fee8e5 100644 --- a/testproject/testproject/templates/base_site.html +++ b/testproject/testproject/templates/base_site.html @@ -10,13 +10,33 @@

Choose bootstrap version

- Bootstrap 2 - Bootstrap 3 - Bootstrap 4 - Bootstrap 4.1.3 - Bootstrap 5 beta3 +

+ Bootstrap 2 +

+

+ Bootstrap 3 +

+

+ +  Bootstrap 4  + + +  Bootstrap 4 (responsive)  + + +  Bootstrap4.1.3  + +

+

+ +  Bootstrap 5 beta3  + + +  Bootstrap 5 beta3 (responsive)  +

+ {% endblock %} @@ -26,6 +46,5 @@

Choose bootstrap version

{% endblock container %} - {% endblock body %} diff --git a/testproject/testproject/urls.py b/testproject/testproject/urls.py index 3228a47..ee34308 100644 --- a/testproject/testproject/urls.py +++ b/testproject/testproject/urls.py @@ -6,8 +6,10 @@ Bootstrap2, Bootstrap3, Bootstrap4, + Bootstrap4Responsive, Bootstrap4_1_3, Bootstrap5, + Bootstrap5Responsive, Index, ) @@ -16,6 +18,16 @@ re_path(r'^bootstrap2/$', Bootstrap2.as_view(), name="bootstrap2"), re_path(r'^bootstrap3/$', Bootstrap3.as_view(), name="bootstrap3"), re_path(r'^bootstrap4/$', Bootstrap4.as_view(), name="bootstrap4"), + re_path( + r'^bootstrap4-responsive/$', + Bootstrap4Responsive.as_view(), + name="bootstrap4responsive", + ), re_path(r'^bootstrap4_1_3/$', Bootstrap4_1_3.as_view(), name="bootstrap4_1_3"), re_path(r'^bootstrap5/$', Bootstrap5.as_view(), name="bootstrap5"), + re_path( + r'^bootstrap5-responsive/$', + Bootstrap5Responsive.as_view(), + name="bootstrap5responsive", + ), ] diff --git a/testproject/testproject/views.py b/testproject/testproject/views.py index 83a9781..06d6257 100644 --- a/testproject/testproject/views.py +++ b/testproject/testproject/views.py @@ -5,7 +5,9 @@ ColumnShiftTableBootstrap2, ColumnShiftTableBootstrap3, ColumnShiftTableBootstrap4, + ColumnShiftTableBootstrap4Responsive, ColumnShiftTableBootstrap5, + ColumnShiftTableBootstrap5Responsive, ) from .models import Author, Book @@ -17,7 +19,6 @@ class Index(TemplateView): class Base(object): - container_css = "span10 offset1" template_name = "testproject/test_bootstrap2.html" table_class_version = ColumnShiftTableBootstrap2 @@ -68,6 +69,12 @@ class Bootstrap4(Base, TemplateView): table_class_version = ColumnShiftTableBootstrap4 +class Bootstrap4Responsive(Base, TemplateView): + container_css = "col-xs-10 col-xs-offset-1" + template_name = "testproject/test_bootstrap4.html" + table_class_version = ColumnShiftTableBootstrap4Responsive + + class Bootstrap4_1_3(Base, TemplateView): container_css = "col-xs-10 col-xs-offset-1" template_name = "testproject/test_bootstrap4.1.3.html" @@ -78,3 +85,9 @@ class Bootstrap5(Base, TemplateView): container_css = "col-xs-10 col-xs-offset-1" template_name = "testproject/test_bootstrap5.html" table_class_version = ColumnShiftTableBootstrap5 + + +class Bootstrap5Responsive(Base, TemplateView): + container_css = "col-xs-10 col-xs-offset-1" + template_name = "testproject/test_bootstrap5.html" + table_class_version = ColumnShiftTableBootstrap5Responsive