Open falkoschindler opened 5 months ago
I've done some searching in Quasar and Vue disciussions and have found these topics, https://github.com/quasarframework/quasar/discussions/16329 and https://github.com/quasarframework/quasar/discussions/15912.
Reading them suggests that rather than being a bug in NiceGUI it's actually a problem with Quasar. Ive looked at the solutions but they involve adding js in the Quasar environemnt - and I'm a bit new to NiceGUI, so struggling to see how NiceGUI can push these code fragments into the Quasar rendering of the nicegui app.
If anyone has a pointer - I will happily pursue the matter :)
Interesting news, @kyloe!
So as far as I understand, they suggest to traverse the tabs once they are mounted. We could wrap the Quasar tab components in order to add such code to the mounted
hook. But I managed to achieve something similar by adding code to TabPanel.__init__
:
class TabPanel(DisableableElement):
def __init__(self, name: Union[Tab, str]) -> None:
# ...
assert isinstance(context.slot.parent, TabPanels)
panels: TabPanels = context.slot.parent
current_tab = panels._props['model-value']
panels.run_method('goTo', self._props['name'])
panels.run_method('goTo', current_tab)
But this causes a visible animation when loading the page. The same happens on the linked codepen https://codepen.io/metalsadman/pen/OJyoYPB.
Is there a better way to do it?
And what's the matter with the mentioned @before-transition
event?
I tried to capture the before-transition event - but it didn't appear to be firing (this is most likely my lack of familiarity with the various layers (ng/quasar/vue) and how they interact, I was probably doing something incorrectly).
My test code to see if the event was firing ...
from nicegui import Client, app, ui, events, Tailwind
import time
columns = [
{'headerName':"Item", 'field': 'item', 'editable': False, 'sortable': False},
{'headerName':"Value",'field': 'value', 'editable': True,'cellDataType':'text'},
]
rows_A = [{"item":"Item A","value":"FOO"},{"item":"Item B","value":"AAA"}]
rows_B = [{"item":"Item A","value":"FOO"},{"item":"Item B","value":"BBB"}]
@ui.page('/')
def main_page() -> None:
grid_A = None
grid_B = None
async def get_data():
msg_A = await grid_A.get_client_data()
print(msg_A)
msg_B = await grid_B.get_client_data()
print(msg_B)
with ui.tabs() as tabs:
tab_A = ui.tab("A")
tab_B = ui.tab("B")
def mounted():
print("Mounted")
with ui.tab_panels(tabs,value=tab_A).on('before-transition',mounted) as panels:
with ui.tab_panel(tab_A) as panel_A:
with ui.element('div').props('ng-if'):
grid_A = ui.aggrid({
'columnDefs': columns,
'rowData': rows_A,
'domLayout': 'autoHeight',
'stopEditingWhenCellsLoseFocus': True
}).style('width: 300px')
with ui.tab_panel(tab_B) as panel_B:
with ui.element('div').props('ng-if'):
grid_B = ui.aggrid({
'columnDefs': columns,
'rowData': rows_B,
'domLayout': 'autoHeight',
'stopEditingWhenCellsLoseFocus': True
}).style('width: 300px')
ui.button("Get data").on('click', lambda: (get_data()))
ui.run(storage_secret='THISISABIGSECRET')
Interesting news, @kyloe!
So as far as I understand, they suggest to traverse the tabs once they are mounted. We could wrap the Quasar tab components in order to add such code to the
mounted
hook. But I managed to achieve something similar by adding code toTabPanel.__init__
:class TabPanel(DisableableElement): def __init__(self, name: Union[Tab, str]) -> None: # ... assert isinstance(context.slot.parent, TabPanels) panels: TabPanels = context.slot.parent current_tab = panels._props['model-value'] panels.run_method('goTo', self._props['name']) panels.run_method('goTo', current_tab)
But this causes a visible animation when loading the page. The same happens on the linked codepen https://codepen.io/metalsadman/pen/OJyoYPB.
Is there a better way to do it? And what's the matter with the mentioned
@before-transition
event?
@falkoschindler
If the property 'animated' is removed when the tabs are instantiated - then the creation process is a lot less unpleasant
with ui.tab_panels(ui_tabs, value=tabs['names'][0]).props(remove='animated') as ui_panels:
I'm still looking for a more elegant solution ...
Description
As noticed in https://github.com/zauberzeug/nicegui/issues/1869#issuecomment-1851381149, when creating AG Grids on currently hidden tabs, they don't get mounted and interacting with them can cause problems:
When clicking "Get data" before visiting tab "Two" for the first time, a JavaScript error occurs and we don't see a notification.
How can we make sure every NiceGUI element is created, even if it is hidden on another tab?
Related discussion: #2157