I have a table with 4 rows. The user is able to select as many rows as they want and when they press continue, a tab for each selected row is visible.
Use case:
A user selects a row and presses continue, a tab is visible. They select a second row from the old table and press continue again. This time 2 tabs are seen but the old selection is persistent. Is there a way to disable this?
The code looks like this:
import dash
from dash import dcc, html, Input, Output, State
import pandas as pd
import pandas as pd
from dash.exceptions import PreventUpdate
import dash_ag_grid as dag
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button("Table", id='get_table'),
html.Div(id='table_div'),
html.Button('Continue', id='continue'),
dcc.Tabs(id = "tabs", persistence=False),
html.Div(id="grid_div"),
dcc.Store(id="selected"),
dcc.Store(id = 'df_dict'),
dcc.Store(id= 'dict'),
])
@app.callback(
Output('table_div', 'children'),
Output('df_dict', 'data'),
Input('get_table', 'n_clicks'),
prevent_initial_call=True
)
def read_table(n_clicks):
if n_clicks:
df = pd.read_csv('table.csv')
dfm = df[["sn","name","path"]]
full_df = df.to_dict()
column_defs = []
for col_index, col_name in enumerate(dfm.columns):
column_defs.append(
{
"headerName": f"{col_name}",
"field": f"{col_name}",
"width": 500,
"resizable": False,
"checkboxSelection": True if col_index == 0 else False,
"filter": True,
}
)
grid = dag.AgGrid(
id="grid",
className="ag-theme-alpine border",
rowData=dfm.to_dict("records"),
columnDefs=column_defs,
columnSize="sizeToFit",
#selectedRows=overlapping,
dashGridOptions={
"domLayout": "autoHeight",
"columnHoverHighlight": True,
"rowSelection": "multiple",
},
style={"height": "100%", "fontSize": "20px"},
)
return grid, full_df
@app.callback(
Output("selected", "data", allow_duplicate=True),
Input("grid", "selectedRows"),
prevent_initial_call=True,
)
def get_user_selections(selected):
if not selected:
raise PreventUpdate
print(selected)
return selected
@app.callback(
Output("tabs", "style"),
Output("tabs", "children"),
Output("dict", "data"),
Input("continue", "n_clicks"),
State("selected", "data"),
State("df_dict", "data"),
prevent_initial_call=True,
)
def get_tabs(n_clicks, selected, df):
tab_names = []
full_path = []
print(f"df{df}")
print(f"selected{selected}")
for rows in selected:
if 'sn' in rows and 'path' in rows:
tab_names.append(f"{rows['path']} - {rows['sn']}")
for key, value in df['sn'].items():
if value == rows['sn'] and df['path'].get(key) == rows['path']:
full_path.append(df['full_path'].get(key))
print(f"tabs:{tab_names}")
n_tabs = len(tab_names)
tabs = [dcc.Tab(label=tab_names[0], value= tab_names[0])]
if n_tabs > 1:
for i in range(2,n_tabs+1):
tabs = tabs + [dcc.Tab(label=tab_names[i-1], value= tab_names[i-1])]
selected_dict = []
for index in range(n_tabs):
selected_dict.append({tab_names[index]: {"fa": full_path[index] , "ft": None}})
print(f"selected:{selected}")
return dict(), tabs, selected_dict
@app.callback(
Output("grid_div", "children"),
Input("tabs", "value"),
State("dict", "data"),
prevent_initial_call=True,
)
def get_grids(value, existing):
if value:
df = pd.read_csv(f"{value}.csv")
column_defs = []
for col_index, col_name in enumerate(df.columns):
column_defs.append(
{
"headerName": f"{col_name}",
"field": f"{col_name}",
"width": 500,
"resizable": False,
"checkboxSelection": True if col_index == 0 else False,
"filter": True,
}
)
overlapping = []
rowData=df.to_dict("records")
print(f"existing:{existing}")
print(f'row:{rowData}')
for item in existing:
if item[value]["ft"] in rowData:
overlapping.append(item[value]["ft"])
grid = dag.AgGrid(
id="table",
rowData=df.to_dict("records"),
columnDefs=column_defs,
columnSize="sizeToFit",
selectedRows=overlapping,
dashGridOptions={
"domLayout": "autoHeight",
"columnHoverHighlight": True,
"rowSelection": "multiple",
},
style={"height": "100%", "fontSize": "20px"},
)
return grid
@app.callback(
Output("dict", "data", allow_duplicate=True),
Input("table","selectedRows"),
State('tabs', 'value'),
State("dict", "data"),
prevent_initial_call=True
)
def store(selectedRows, dropdown_value, data):
for items in data:
items[dropdown_value]["ft"]=selectedRows
print(f"data{data}")
return data
if __name__ == '__main__':
app.run_server(debug=True)
and the csv file with the table:
sn,name,path,full_path
123,a,1,fp1
123,a,2,fp2
345,c,1,fp3
345,c,3,fp4