I created a panel app to create a form to take inputs to store into a database for analysis later.
Using Panel 1.0.3
In the example below there is a Customer
form and an Employee
form.
Code:
import panel as pn
class Customer:
def __init__(self):
self.customer_name = pn.widgets.TextInput(name="Customer Name", width=500)
self.customer_address = pn.widgets.TextAreaInput(
name="Customer Address", width=500
)
self.store = pn.widgets.Button(name="Store")
self.store.on_click(self.store_cus)
@property
def display(self):
return pn.Column(self.customer_name, self.customer_address, self.store)
def store_cus(self, event):
print("Store to Database")
class Employee:
def __init__(self):
self.employee_name = pn.widgets.TextInput(name="Employee Name", width=500)
self.employee_email = pn.widgets.TextInput(name="Employee Email", width=500)
self.store = pn.widgets.Button(name="Store")
self.store.on_click(self.store_emp)
@property
def display(self):
return pn.Column(self.employee_name, self.employee_email, self.store)
def store_emp(self, event):
print("Store to Database")
class Navbar:
def __init__(self):
self.left_nav_bar = pn.widgets.Select(
name="Choose", options=["Customers", "Employees"]
)
self.customer_tabs = Customer()
self.employee_tabs = Employee()
self.display_form = pn.bind(self.update_on_nav_bar, navbar=self.left_nav_bar)
def update_on_nav_bar(self, navbar):
if navbar == "Employees":
return self.employee_tabs.display
else:
return self.customer_tabs.display
# return self.display_form
@pn.depends("left_nav_bar.value")
def display(self):
if self.left_nav_bar.value == "Employees":
return self.employee_tabs.display
else:
return self.customer_tabs.display
if __name__ == "__main__":
nav = Navbar()
template = pn.template.MaterialTemplate(title="CustEmp")
template.main.append(
pn.Column(
pn.Row(
nav.left_nav_bar,
nav.display,
nav.display_form,
),
)
)
pn.serve(template)
The drop down menu is used to switch between Customer
and Employee
forms
Output:
On Changing the drop down menu
results in error from
pn.bind
(I think)
2023-05-29 18:59:41,958 ERROR: panel.reactive - Callback failed for object named "Choose" changing property {'value': 'Customers'}
Traceback (most recent call last):
File "C:\Users\<path-to-env>\lib\site-packages\panel\reactive.py", line 379, in _process_events
self.param.update(**self_events)
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 1902, in update
self_._batch_call_watchers()
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 2063, in _batch_call_watchers
self_._execute_watcher(watcher, events)
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 2025, in _execute_watcher
watcher.fn(*args, **kwargs)
File "C:\Users\<path-to-env>\lib\site-packages\panel\param.py", line 827, in _replace_pane
self._update_inner(new_object)
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 700, in _update_inner
new_pane, internal = self._update_from_object(
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 655, in _update_from_object
cls._recursive_update(old_object, i, old, new)
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 629, in _recursive_update
old.param.update(**new_params)
AttributeError: 'str' object has no attribute 'param'
Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x0000020567533DF0>>, <Task finished name='Task-345' coro=<ServerSession.with_document_locked() done, defined at C:\Users\<path-to-env>\lib\site-packages\bokeh\server\session.py:77> exception=AttributeError("'str' object has no attribute 'param'")>)
Traceback (most recent call last):
File "C:\Users\<path-to-env>\lib\site-packages\tornado\ioloop.py", line 738, in _run_callback
ret = callback()
File "C:\Users\<path-to-env>\lib\site-packages\tornado\ioloop.py", line 762, in _discard_future_result
future.result()
File "C:\Users\<path-to-env>\lib\site-packages\bokeh\server\session.py", line 98, in _needs_document_lock_wrapper
result = await result
File "C:\Users\<path-to-env>\lib\site-packages\panel\reactive.py", line 424, in _change_coroutine
state._handle_exception(e)
File "C:\Users\<path-to-env>\lib\site-packages\panel\io\state.py", line 432, in _handle_exception
raise exception
File "C:\Users\<path-to-env>\lib\site-packages\panel\reactive.py", line 422, in _change_coroutine
self._change_event(doc)
File "C:\Users\<path-to-env>\lib\site-packages\panel\reactive.py", line 440, in _change_event
self._process_events(events)
File "C:\Users\<path-to-env>\lib\site-packages\panel\reactive.py", line 379, in _process_events
self.param.update(**self_events)
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 1902, in update
self_._batch_call_watchers()
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 2063, in _batch_call_watchers
self_._execute_watcher(watcher, events)
File "C:\Users\<path-to-env>\lib\site-packages\param\parameterized.py", line 2025, in _execute_watcher
watcher.fn(*args, **kwargs)
File "C:\Users\<path-to-env>\lib\site-packages\panel\param.py", line 827, in _replace_pane
self._update_inner(new_object)
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 700, in _update_inner
new_pane, internal = self._update_from_object(
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 655, in _update_from_object
cls._recursive_update(old_object, i, old, new)
File "C:\Users\<path-to-env>\lib\site-packages\panel\pane\base.py", line 629, in _recursive_update
old.param.update(**new_params)
AttributeError: 'str' object has no attribute 'param'
Two questions:
- Why does
nav.display
show the text and not render of the actual panel widgets?
The code executes throughdisplay
property/method as well, but only renders the text and the the actual widgets. - On changing the drop down menu - why does
display_form
result in error? What can I do to work around it?
I have been at this for a few hours and can’t seem to make sense of this. Any ideas?