pythonquasar-frameworknicegui

NiceGUI tables : How to use selection and click events


I want to either click or select a single row in a table, retrieve the corresponding row's data, and then process it further with handlers. But the documentation is slim at the moment, and I have never used Quasar or Vue.js before.

Here's my attempt:

from nicegui import ui

columns = [
    {'name': 'title', 'label': 'Title', 'field':'title', 'required': True, 'align': 'left'},
    {'name': 'author', 'label': 'Author', 'field':'author', 'align': 'left'},
    {'name': 'year', 'label': 'Year', 'field':'year', 'sortable': True, 'align': 'left'},
]

rows = [
    {'title': 'Some title A', 'url' : 'https://example.com/search?q=A', 'author': 'Alice', 'year': 2023},
    {'title': 'Some title B', 'url' : 'https://example.com/search?q=B', 'author': 'Bob', 'year': 2022},
    {'title': 'Some title C', 'url' : 'https://example.com/search?q=C', 'author': 'Carol', 'year': 2021}
]
table = ui.table(title='Example table', columns=columns, rows=rows, row_key='name', pagination=5,
                selection='single',  on_select=lambda e: ui.notify(e.selection))
table.add_slot('body', r'''
    <q-tr :props="props" @row-click="rowClick">
        <q-td>
            <a :href="props.row.url">{{ props.row.title }}</a>
        </q-td>
        <q-td>{{ props.row.author }}</q-td>
        <q-td>{{ props.row.year }}</q-td>
    </q-tr>
    ''')
table.on('rowClick', lambda *args: print(args), [None, None, None]) # c.f. nicegui issues #664, #672, #1095

ui.run()

The code above does not work. There are no exceptions, but nothing is happening if I click on a row (and the check boxes to select a row are not shown; I might have disabled them inadvertently using my template).

If i I had to choose, I would prefer to handle a click event.


Solution

  • Here is a working example table:

    table = ui.table(title='Example table', columns=columns, rows=rows, row_key='title', pagination=5, selection='single')
    table.add_slot('body-cell-title', r'<td><a :href="props.row.url">{{ props.row.title }}</a></td>')
    table.on('rowClick', lambda e: print(e.args))
    

    It looks like your body template broke the row-click event, but I'm not 100% sure. Anyway, using the "body-cell-title" slot, you don't need to write the template for the whole body, but for the "title" cell only.

    And note that, when using features like filters and selection, the row_key should match a column name with unique values. Here I'm using "title".