Hi there,
I’m facing a strange behaviour of Panel (or maybe of me?).
After applying How to get columns of uploaded excel file?, I managed to bind my Tabulator table with a file upload widget. But after enhancing the code with a second bind, the bindings (neither the second nor the first) seem to work.
My page looks like this:
and aims to:
- upload by default the project file ‘default.proj.json’ into Tabulator as a DataFrame
- allow to upload a different project file with bound upload widget saved in filesystem
- edit the Tabulator table and checking the input consistency against regex rules
- save the changes inot the opened file (or default) with a button widget (for the time being it only prints the DataFrame)
As a result, the bindings do not seem to work since the alert states do not change and the ‘print’ does not happen.
My code is as follows (well I summarized it a bit for readability):
import io
import re
import panel as pn
import pandas as pd
(...)
def get_data1(file):
if file is not None:
alert1a.object = 'Loading file'
df = pd.read_json(io.BytesIO(file))
alert1a.object = 'File loaded'
btn_save1.visible = True
table1.value = df
return df
return pd.DataFrame()
upload1 = pn.widgets.FileInput(accept='.json', multiple=False)
if 'uploaded1' not in globals():
uploaded1 = pd.read_json('./apps/default.proj.json', dtype='str')
else:
uploaded1 = pn.bind(get_data1, file=upload1).rx() # extract a reactive df
alert1a = pn.pane.Alert('Waiting for file upload', alert_type='light')
# TABLE section
def table1_changed(event):
MASK = {'0':FLOAT_MASK,
'1':COLOR_MASK,
'2':FLOAT_MASK,
'3':REGEX_MASK,
'4':BOOL_MASK,
'5':DIR_MASK,
'6':REGEX_MASK,
'7':LIST_MASK
}
if event.value != event.old:
if re.findall(MASK[str(event.row)],event.value):
alert1b.object = 'No error'
alert1b.alert_type = 'light'
btn_save1.visible = True
else:
alert1b.object = f'Format error @ row {event.row}. Project file cannot be saved.'
alert1b.alert_type = 'warning'
btn_save1.visible = False
alert1b = pn.pane.Alert('No error', alert_type='light')
table1 = pn.widgets.Tabulator(uploaded1,
width=1500,
height=720,
disabled=False,
layout='fit_data_fill',
sortable=True,
on_edit=lambda e: table1_changed(e),
pagination='remote',
stylesheets=[stylesheet],
header_filters=False,
page_size=25,
)
# SAVE btn section
def save_data1(bool, df):
print(df)
btn_save1.visible = False
return
btn_save1 = pn.widgets.Button(name='Save', button_type='primary', visible=False)
table1_saved = pn.bind(save_data1, bool=btn_save1, df=table1)
tab1 = pn.GridSpec(sizing_mode='stretch_both')
tab1[0,:] = pn.pane.Markdown('## Project File to upload') # header line
tab1[1:15,0] = pn.Column( # sidebar
upload1,
alert1a,
)
tab1[1:15,1:5] = pn.Column( # body
alert1b,
btn_save1,
table1,
)
tabs = pn.Tabs(('Upload PF', tab1))
tabs.servable()
Sorry for such a long topic, but I have no clue what I’m missing here.