justpy-org / justpy

An object oriented high-level Python Web Framework that requires no frontend programming
https://justpy.io
Apache License 2.0
1.22k stars 96 forks source link

can not add a new ag_grid after delete the old grid #578

Closed wangw37 closed 2 years ago

wangw37 commented 2 years ago

Code like below, it is sure button click callback function works fine If only delete_components(), grid will disappeared. But if I want add a new grid, old grid display instead of the new grid which I want.

import justpy as jp
import pandas as pd

date_frame = pd.DataFrame(data= {'col1': [1, 2], 'col2': [11, 22]})
date_frame1 = pd.DataFrame(data= {'col1': [10, 20], 'col2': [11, 22], 'col3': [111, 222]})

class Test():
    def __init__(self, wp):
        self.wp = wp
        self.b = jp.Button(a=self.wp, text='button', classes='mt-1 w-fit px-4 py-2 rounded-md border border-gray-300 shadow-sm bg-green-200 text-red-700')
        self.d = jp.Div(a=self.wp)
        self.b.on('click', self.button_click)

    def grid(self):
        grid = date_frame.jp.ag_grid(a=self.d)
        return self.wp

    def button_click(self, msg):
        self.d.delete_components()
        grid = date_frame1.jp.ag_grid(a=self.d)

wp = jp.WebPage()
jp.justpy(Test(wp).grid)
WolfgangFahl commented 2 years ago

@wangw37 thank you for the issue report The code you provided looks somewhat inadequate to me for the use case you seem to have in mind. As far as i understand you'd like to select from different date_frame options on the click of a button.

Since justpy is reactive you simply have to modify the ag_grid on the click of the button by reloading the dataframe to the aggrid. No need to delete and replace the component. Please also note how async might be used on the click of the button.

The way you setup the Webpage and pass it in is somewhat incompatible to the initialization style of our demos and the future ideas we have on initialization see e.g. how we have a "content()" function in boostrap based justpy widgets apps e.g. https://github.com/WolfgangFahl/pyJustpyWidgets/blob/main/jpdemo/examples/jpTableDemo.py in the justpy widgets project.

If you'd like to simplify your ag-grid handling you might also want to look into https://nicegui.io/

WolfgangFahl commented 2 years ago

Issue578 shows the result when the code is as below. See also https://justpy-demo.herokuapp.com/demo/issue_578_new_aggrid if the link above does not work try the docker version of the demos install things locally or wait until #574 is fixed to host your own demo browser version in heroku.

 """
Created on 2022-10-21

@author: wangw37
"""
import justpy as jp
import pandas as pd

class TestIssue578():
    """ 
    test for Issue 578

    see https://github.com/justpy-org/justpy/issues/578
    """
    def __init__(self,data_frames:list):
        """
        constructor
        """
        if len(data_frames)<1:
            raise Exception("There needs to be at least one data frame")
        self.data_frames=data_frames
        self.data_frame_index=0

    def next_index(self):
        """
        calculate the next index
        """
        return (self.data_frame_index+1) % len(self.data_frames)

    def next_button_text(self):
        """
        calculate the button text for selecting the next index
        """
        n_index=self.next_index()
        return f"show dataframe {n_index}"

    def content(self):
        """
        the browser main web page
        """
        self.wp =jp.WebPage()
        self.button = jp.Button(a=self.wp, text=self.next_button_text(), classes='mt-1 w-fit px-4 py-2 rounded-md border border-gray-300 shadow-sm bg-green-200 text-red-700')
        self.div = jp.Div(a=self.wp)
        self.ag_grid=jp.AgGrid(a=self.div)
        self.load_dataframe()
        self.button.on('click', self.button_click)
        return self.wp

    def load_dataframe(self):
        """
        load the dataframe for the current index
        """
        self.ag_grid.load_pandas_frame(self.data_frames[self.data_frame_index])

    async def button_click(self, _msg):
        """
        react on the button click
        """
        self.data_frame_index=self.next_index()
        self.load_dataframe()
        self.button.text=self.next_button_text()

def grid_test_issue578():
    """
    setup the TestIssue class and 
    """
    data_frame = pd.DataFrame(data= {'col1': [1, 2], 'col2': [11, 22]})
    data_frame1 = pd.DataFrame(data= {'col1': [10, 20], 'col2': [11, 22], 'col3': [111, 222]})
    testIssue578=TestIssue578(data_frames=[data_frame,data_frame1])
    return testIssue578.content()

from examples.basedemo import Demo
Demo("Issue 578 new_aggrid", grid_test_issue578)

which is now also available in the demo browser

wangw37 commented 2 years ago

Thank you so much, you are so patient with me as a beginner ;-)

WolfgangFahl commented 2 years ago

@wangw37 your are most welcome. See also the https://github.com/justpy-org/justpy/blob/master/docs/blog/heroku.md on how you can get your own heroku justpy demo browser. It would be great if you try it out and give us feedback!