How can i make button in table cell using NiceGui library?

Question:

from nicegui import ui

Called when a button in a cell is clicked:

def buttonClick(*args):
    print(args)
    
table = ui.table({
    'columnDefs': [
        {'headerName': 'Task id', 'field': 'taskId'},

This is how i am trying to add a button to the table:

        {
            'headerName': "Info",
            'field': "info", 
            'cellRenderer': 'buttonRenderer',
            'cellRendererParams': {
                'onClick': buttonClick,
                'label': 'Check',
            }
        },
    ],
    'rowData': [
        {
            'taskId': 1,
        },
    ],
})
    
ui.run()

I get an exception:

Traceback (most recent call last):
  File "/home/stanislav/.local/lib/python3.8/site-packages/starlette/websockets.py", line 171, in send_json
    text = json.dumps(data)
  File "/usr/lib/python3.8/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type function is not JSON serializable
Asked By: Stan Sakun

||

Answers:

Currently custom button renderers are not supported in NiceGUI. This is due to a missing renderer in JustPy, which only provides a checkboxRenderer.

But via the underlying JustPy view you can at least register a handler for the cellClicked event:

from nicegui import ui

table = ui.table({
    'columnDefs': [
        {'headerName': 'Task id', 'field': 'taskId'},
        {'headerName': 'Info', 'field': 'info'},
    ],
    'rowData': [
        {'taskId': 1},
    ],
})

def handle_click(sender, msg):
    print(sender)
    print(msg)

table.view.on('cellClicked', handle_click)

ui.run()

The output contains plenty information about which cell has been clicked:

AgGrid(id: 1, vue_type: grid, Grid options: {'columnDefs': [{'headerName': 'Task id', 'field': 'taskId'}, {'headerName': 'Info', 'field': 'info'}], 'rowData': [{'taskId': 1}]})
{'event_type': 'cellClicked', 'grid': 'ag-grid', 'id': 1, 'vue_type': 'grid', 'page_id': 0, 'websocket_id': 0, 'value': 1, 'rowIndex': 0, 'data': {'taskId': 1}, 'colId': 'taskId', 'selected': False, 'rowHeight': 28, 'session_id': '6e64e0654d1e48fa9e76c97e20681319', 'msg_type': 'event', 'page': Page(page_id: 0, number of components: 1, reload interval: None), 'websocket': <starlette.websockets.WebSocket object at 0x11f2ea470>, 'target': AgGrid(id: 1, vue_type: grid, Grid options: {'columnDefs': [{'headerName': 'Task id', 'field': 'taskId'}, {'headerName': 'Info', 'field': 'info'}], 'rowData': [{'taskId': 1}]})}

Update for NiceGUI 1.0+

Since version 1.0 NiceGUI doesn’t use JustPy anymore. That’s why there is no view. But it has now its own generic event subscription which can be used to subscribe to table events:

table.on('cellClicked', handle_click)

Here you can find a list of events with corresponding event arguments, most of which are accessible in Python.

Answered By: Falko