table.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from typing import Any, Callable, Dict, List, Optional
  2. from typing_extensions import Literal
  3. from ..dependencies import register_component
  4. from ..element import Element
  5. from ..events import TableSelectionEventArguments, handle_event
  6. from .mixins.filter_element import FilterElement
  7. register_component('nicegui-table', __file__, 'table.js')
  8. class Table(FilterElement):
  9. def __init__(self,
  10. columns: List[Dict],
  11. rows: List[Dict],
  12. row_key: str = 'id',
  13. title: Optional[str] = None,
  14. selection: Optional[Literal['single', 'multiple']] = None,
  15. pagination: Optional[int] = None,
  16. on_select: Optional[Callable[..., Any]] = None,
  17. ) -> None:
  18. """Table
  19. A table based on Quasar's `QTable <https://quasar.dev/vue-components/table>`_ component.
  20. :param columns: list of column objects
  21. :param rows: list of row objects
  22. :param row_key: name of the column containing unique data identifying the row (default: "id")
  23. :param title: title of the table
  24. :param selection: selection type ("single" or "multiple"; default: `None`)
  25. :param pagination: number of rows per page (`None` hides the pagination, 0 means "infinite"; default: `None`)
  26. :param on_select: callback which is invoked when the selection changes
  27. If selection is 'single' or 'multiple', then a `selected` property is accessible containing the selected rows.
  28. """
  29. super().__init__(tag='nicegui-table')
  30. self.rows = rows
  31. self.row_key = row_key
  32. self.selected: List[Dict] = []
  33. self._props['columns'] = columns
  34. self._props['rows'] = rows
  35. self._props['row-key'] = row_key
  36. self._props['title'] = title
  37. self._props['hide-pagination'] = pagination is None
  38. self._props['pagination'] = {'rowsPerPage': pagination or 0}
  39. self._props['selection'] = selection or 'none'
  40. self._props['selected'] = self.selected
  41. def handle_selection(msg: Dict) -> None:
  42. if msg['args']['added']:
  43. if selection == 'single':
  44. self.selected.clear()
  45. self.selected.extend(msg['args']['rows'])
  46. else:
  47. self.selected[:] = [row for row in self.selected if row[row_key] not in msg['args']['keys']]
  48. self.update()
  49. arguments = TableSelectionEventArguments(sender=self, client=self.client, selection=self.selected)
  50. handle_event(on_select, arguments)
  51. self.on('selection', handle_selection)
  52. def add_rows(self, *rows: Dict) -> None:
  53. """Add rows to the table."""
  54. self.rows.extend(rows)
  55. self.update()
  56. def remove_rows(self, *rows: Dict) -> None:
  57. """Remove rows from the table."""
  58. keys = [row[self.row_key] for row in rows]
  59. self.rows[:] = [row for row in self.rows if row[self.row_key] not in keys]
  60. self.update()
  61. class row(Element):
  62. def __init__(self) -> None:
  63. super().__init__('q-tr')
  64. class header(Element):
  65. def __init__(self) -> None:
  66. super().__init__('q-th')
  67. class cell(Element):
  68. def __init__(self, key: str = '') -> None:
  69. super().__init__('q-td')
  70. if key:
  71. self._props['key'] = key