# Imports
from django.utils.safestring import mark_safe
from .base import Element
# Exports
__all__ = (
"Column",
"Datum",
"Row",
"Table",
)
# Classes
[docs]class Column(Element):
"""A column (header) in an HTML table."""
[docs] def __init__(self, name, help_text=None, label=None, **kwargs):
"""Initialize the column.
:param name: The programmatic name of the column. For example, the field name.
:type name: str
:param help_text: Help text for the column.
:type help_text: str
:param label: The column label. If omitted, the name is converted into a label.
:type label: str
"""
self.help_text = help_text
self.label = label or name.replace("_", " ").title()
self.name = name
super().__init__("th", content=str(self.label), **kwargs)
@property
def title(self):
"""Get the column label. Alias for ``label``."""
return self.label
class Datum(Element):
"""An individual td within a table."""
def __init__(self, value, **kwargs):
super().__init__("td", content=str(value), **kwargs)
[docs]class Row(Element):
"""A row in an HTML table."""
[docs] def __init__(self, data, **kwargs):
"""Initialize the row.
:param data: The data to be included in the row.
:type data: list | tuple
"""
super().__init__("tr", **kwargs)
self._data = data
@property
def data(self):
"""Alias for ``_data``."""
return self._data
[docs] @mark_safe
def to_html(self):
"""Export the row to HTML."""
a = list()
a.append(self.get_open_tag())
for d in self._data:
if isinstance(d, Datum):
a.append(d.to_html())
else:
a.append("<td>%s</td>" % d)
a.append(self.get_close_tag())
return "\n".join(a)
[docs]class Table(Element):
"""An HTML table."""
[docs] def __init__(self, caption=None, columns=None, rows=None, **kwargs):
"""Initialize the table.
:param caption: Optional caption for the table.
:type caption: str
:param columns: The columns to be included in the table.
:type columns: list[superdjango.html.library.Column]
:param rows: The rows to be included in the table.
:type rows: list[superdjango.html.library.Row]
"""
super().__init__("table", **kwargs)
self.caption = caption
self.columns = columns or list()
self.rows = rows or list()
def __iter__(self):
return iter(self.rows)
[docs] def column(self, name, help_text=None, label=None, **kwargs):
"""Add a column to the table.
:param name: The programmatic name of the column. For example, the field name.
:type name: str
:param help_text: Help text for the column.
:type help_text: str
:param label: The column label. If omitted, the name is converted into a label.
:type label: str
:rtype: superdjango.html.library.Column
"""
column = Column(name, help_text=help_text, label=label, **kwargs)
self.columns.append(column)
return column
[docs] def row(self, data, **kwargs):
"""Add a row to the table.
:param data: The data to be included in the row.
:type data: list | tuple
:rtype: superdjango.html.library.Row
"""
row = Row(data, **kwargs)
self.rows.append(row)
return row
[docs] @mark_safe
def to_html(self):
"""Export the table as HTML.
:rtype: str
"""
a = list()
a.append(self.get_open_tag())
if self.caption is not None:
caption = Element("caption", content=self.caption)
a.append(caption.to_html())
a.append("<thead><tr>")
for column in self.columns:
a.append(column.to_html())
a.append("</tr></thead>")
a.append("<tbody>")
for row in self.rows:
a.append(row.to_html())
a.append("</tbody>")
a.append(self.get_close_tag())
return "\n".join(a)