浏览代码

Merge pull request #1061 from zauberzeug/sort-and-format

Support dynamic column attributes for ui.table
Rodja Trappe 1 年之前
父节点
当前提交
4954fca019

+ 3 - 2
nicegui/dependencies.py

@@ -82,6 +82,7 @@ def generate_js_imports(prefix: str) -> str:
     for name, component in js_components.items():
         if name in globals.excludes:
             continue
-        result += f'import {{ default as {name} }} from "{prefix}{component.import_path}";\n'
-        result += f'app.component("{name}", {name});\n'
+        var_name = name.replace('-', '_')
+        result += f'import {{ default as {var_name} }} from "{prefix}{component.import_path}";\n'
+        result += f'app.component("{name}", {var_name});\n'
     return result

+ 30 - 0
nicegui/elements/table.js

@@ -0,0 +1,30 @@
+export default {
+  template: `
+    <q-table v-bind="$attrs" :columns="convertedColumns">
+      <template v-for="(_, slot) in $slots" v-slot:[slot]="slotProps">
+        <slot :name="slot" v-bind="slotProps || {}" />
+      </template>
+    </q-table>
+  `,
+  props: {
+    columns: Array,
+  },
+  computed: {
+    convertedColumns() {
+      return this.columns.map((column) => {
+        const convertedColumn = { ...column };
+        for (const attr in convertedColumn) {
+          if (attr.startsWith(":")) {
+            try {
+              convertedColumn[attr.slice(1)] = new Function("return " + convertedColumn[attr])();
+              delete convertedColumn[attr];
+            } catch (e) {
+              console.error(`Error while converting ${attr} attribute to function:`, e);
+            }
+          }
+        }
+        return convertedColumn;
+      });
+    },
+  },
+};

+ 4 - 1
nicegui/elements/table.py

@@ -2,10 +2,13 @@ from typing import Any, Callable, Dict, List, Optional
 
 from typing_extensions import Literal
 
+from ..dependencies import register_component
 from ..element import Element
 from ..events import TableSelectionEventArguments, handle_event
 from .mixins.filter_element import FilterElement
 
+register_component('nicegui-table', __file__, 'table.js')
+
 
 class Table(FilterElement):
 
@@ -32,7 +35,7 @@ class Table(FilterElement):
 
         If selection is 'single' or 'multiple', then a `selected` property is accessible containing the selected rows.
         """
-        super().__init__(tag='q-table')
+        super().__init__(tag='nicegui-table')
 
         self.rows = rows
         self.row_key = row_key

+ 8 - 0
tests/test_table.py

@@ -102,3 +102,11 @@ def test_single_selection(screen: Screen):
     screen.find('Bob').find_element(By.XPATH, 'preceding-sibling::td').click()
     screen.wait(0.5)
     screen.should_contain('1 record selected.')
+
+
+def test_dynamic_column_attributes(screen: Screen):
+    ui.table(columns=[{'name': 'age', 'label': 'Age', 'field': 'age', ':format': 'value => value + " years"'}],
+             rows=[{'name': 'Alice', 'age': 18}])
+
+    screen.open('/')
+    screen.should_contain('18 years')

+ 30 - 0
website/more_documentation/table_documentation.py

@@ -160,3 +160,33 @@ def more() -> None:
             {'name': 'count', 'label': 'Count', 'field': 'count'},
         ]
         table = ui.table(columns=columns, rows=[], row_key='id').classes('w-full')
+
+    @text_demo('Custom sorting and formatting', '''
+        You can define dynamic column attributes using a `:` prefix.
+        This way you can define custom sorting and formatting functions.
+
+        The following example allows sorting the `name` column by length.
+        The `age` column is formatted to show the age in years.
+    ''')
+    def custom_formatting():
+        columns = [
+            {
+                'name': 'name',
+                'label': 'Name',
+                'field': 'name',
+                'sortable': True,
+                ':sort': '(a, b, rowA, rowB) => b.length - a.length',
+            },
+            {
+                'name': 'age',
+                'label': 'Age',
+                'field': 'age',
+                ':format': 'value => value + " years"',
+            },
+        ]
+        rows = [
+            {'name': 'Alice', 'age': 18},
+            {'name': 'Bob', 'age': 21},
+            {'name': 'Carl', 'age': 42},
+        ]
+        ui.table(columns=columns, rows=rows, row_key='name')