javascriptpythonnicegui

How can I reuse a function in NiceGUI slots without client-side code duplication?


NiceGUI documentation on conditional formatting in Table suggests the following:

table.add_slot('body-cell-age', '''
    <q-td key="age" :props="props">
        <q-badge :color="props.value < 21 ? 'red' : 'green'">
            {{ props.value }}
        </q-badge>
    </q-td>
''')

This has a very simple logic, namely props.value < 21 ? 'red' : 'green'

I do want to put way more advanced formatting logic here, and reuse it across the entire app - in many slots of many different components. I do not want to just inline the same code snippet for each slot as this will result in a lot of extra code duplication on the client side. Instead, I want to define a function once, and call it from each slot.

How can I do it?

I tried attaching a function to window by adding <script> with ui.add_head_html but it was not recognized in my slot.

I tried using custom VUE component for my slot definition but then it doesn't appear to populate props.


Solution

  • Defining a global JavaScript function to be used in props and templates is currently an open question: https://github.com/zauberzeug/nicegui/discussions/3754

    One possible workaround is to augment the table rows with an additional pre-computed color attribute:

    columns = [
        {'name': 'name', 'label': 'Name', 'field': 'name'},
        {'name': 'age', 'label': 'Age', 'field': 'age'},
    ]
    rows = [
        {'name': 'Alice', 'age': 18},
        {'name': 'Bob', 'age': 21},
    ]
    for row in rows:
        row['color'] = 'red' if row['age'] < 21 else 'green'
    table = ui.table(columns=columns, rows=rows, row_key='name')
    table.add_slot('body-cell-age', '''
        <q-td key="age" :props="props">
            <q-badge :color="props.row.color">
                {{ props.value }}
            </q-badge>
        </q-td>
    ''')