A small update on this since i’ve been using it on a project and have enhanced the custom formatters feature - you can now use a function that returns a component…
inspired by @meredydd original datagrid show and tell (before data grids existed in anvil…)
simple example
set the column formatter to a function
that returns a link
with a click_event
.
self.columns = [
...
{'title':"Name", 'field':'name', 'formatter': self.name_foramtter}
...
]
# must include a row argument and **kwargs
def name_formatter(self, row, **params):
def link_click(**event_args):
print(row)
link = Link(text = row['name'])
link.set_event_handler('click', link_click)
# return a component
return link
more in-depth
My use case was a cell that had 5 status icons.
when the status icon was clicked it would then update the database and change color accordingly…
class Form(FormTemplate):
def __init__(self, **properties):
self.columns = [
...
{'title':"Status", 'field':'status', 'formatter': self.status}
...
]
self.status
is a function
that returns a flow_panel
with links
icons = ['fa:ban', 'fa:exchange', 'fa:database', 'fa:envelope', 'fa:check']
spacing = dict(spacing_above='none', spacing_below='none')
def status(self, row, **kwargs):
def status_clicked(sender, **event_args):
for link in links[sender.tag+1:]:
link.foreground = "theme:Gray 300"
for link in links[:sender.tag+1]:
color = f"theme:{sender.tag}" # colors defined in theme
link.foreground = color
if row['status'] != sender.tag:
row['status'] = sender.tag
self.tabulator.update_row(row['id'], row)
anvil.server.call_s('update_row', row)
panel = FlowPanel(**self.spacing)
links = []
current_status = row['status']
current_link = None
for i,icon in enumerate(self.icons):
link = Link(icon=icon, tag=i, **self.spacing)
panel.add_component(link)
links.append(link)
link.set_event_handler('click', status_clicked)
if current_status == i:
current_link = link
status_clicked(sender=current_link)
# return a component to be rendered for the cell
return panel
This could also be down with a form and databindings - but sometimes I find databindings a little slow and it can be nice to just do something in code…