diff --git a/horizon/dashboards/settings/project/templates/project/_openrc.html b/horizon/dashboards/settings/project/templates/project/_openrc.html index b8deaa9c3..9c0f89e5b 100644 --- a/horizon/dashboards/settings/project/templates/project/_openrc.html +++ b/horizon/dashboards/settings/project/templates/project/_openrc.html @@ -27,6 +27,6 @@ {% endblock %} {% block modal-footer %} - + {% if hide %}{% trans "Cancel" %}{% endif %} {% endblock %} diff --git a/horizon/tables/base.py b/horizon/tables/base.py index f1d4e3815..0dd746c7c 100644 --- a/horizon/tables/base.py +++ b/horizon/tables/base.py @@ -789,10 +789,11 @@ class DataTable(object): """ __metaclass__ = DataTableMetaclass - def __init__(self, request, data=None, **kwargs): + def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs): self._meta.request = request self._meta.data = data self.kwargs = kwargs + self._needs_form_wrapper = needs_form_wrapper # Create a new set columns = [] @@ -909,6 +910,28 @@ class DataTable(object): % lookup) return matches[0] + @property + def has_actions(self): + """ + Boolean. Indicates whether there are any available actions on this + table. + """ + if not self.base_actions: + return False + return any(self.get_table_actions()) or any(self._meta.row_actions) + + @property + def needs_form_wrapper(self): + """ + Boolean. Indicates whather this table should be rendered wrapped in + a ``
`` tag or not. + """ + # If needs_form_wrapper is explicitly set, defer to that. + if self._needs_form_wrapper is not None: + return self._needs_form_wrapper + # Otherwise calculate whether or not we need a form element. + return self.has_actions + def get_table_actions(self): """ Returns a list of the action instances for this table. """ bound_actions = [self.base_actions[action.name] for diff --git a/horizon/templates/horizon/common/_data_table.html b/horizon/templates/horizon/common/_data_table.html index 6aabcca0a..89db10b46 100644 --- a/horizon/templates/horizon/common/_data_table.html +++ b/horizon/templates/horizon/common/_data_table.html @@ -1,6 +1,7 @@ {% load i18n %} +{% with table.needs_form_wrapper as needs_form_wrapper %}
- {% csrf_token %} + {% if needs_form_wrapper %}{% csrf_token %}{% endif %} {% with columns=table.get_columns rows=table.get_rows %} @@ -49,5 +50,6 @@
{% endwith %} - + {% if needs_form_wrapper %}{% endif %}
+{% endwith %} \ No newline at end of file diff --git a/horizon/tests/table_tests.py b/horizon/tests/table_tests.py index b7be8e63b..94478f6b0 100644 --- a/horizon/tests/table_tests.py +++ b/horizon/tests/table_tests.py @@ -175,6 +175,16 @@ class MyTable(tables.DataTable): row_actions = (MyAction, MyLinkAction, MyBatchAction, MyToggleAction) +class NoActionsTable(tables.DataTable): + id = tables.Column('id') + + class Meta: + name = "no_actions_table" + verbose_name = _("No Actions Table") + table_actions = () + row_actions = () + + class DataTableTests(test.TestCase): def test_table_instantiation(self): """ Tests everything that happens when the table is instantiated. """ @@ -625,3 +635,22 @@ class DataTableTests(test.TestCase): self.assertNotContains(res, '3.0') self.assertNotContains(res, '6') + + def test_table_action_attributes(self): + table = MyTable(self.request, TEST_DATA) + self.assertTrue(table.has_actions) + self.assertTrue(table.needs_form_wrapper) + res = http.HttpResponse(table.render()) + self.assertContains(res, "