Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tabulator.on_click callback #3245

Merged
merged 3 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion examples/reference/widgets/Tabulator.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
"* **``current_view``** (``DataFrame``): The current view of the table that is displayed, i.e. after sorting and filtering are applied\n",
"* **``selected_dataframe``** (``DataFrame``): A DataFrame reflecting the currently selected rows.\n",
"\n",
"##### Callbacks\n",
"\n",
"* **``on_click``**: Allows registering callbacks which are given `CellClickEvent` objects containing the `column`, `row` and `value` of the clicked cell.\n",
"* **``on_edit``**: Allows registering callbacks which are given `TableEditEvent` objects containing the `column`, `row`, `value` and `old` value.\n",
"\n",
"___"
]
},
Expand Down Expand Up @@ -559,6 +564,27 @@
"pn.widgets.Tabulator(sel_df, selectable_rows=lambda df: list(range(0, len(df), 2)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To trigger events based on an exact cell that was clicked you may also register an `on_click` callback which is called whenever a cell is clicked."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def click(event):\n",
" print(f'Clicked cell in {event.column} column, row {event.row}')\n",
"\n",
"select_table.on_click(click) \n",
"# Optionally we can also limit the callback to a specific column\n",
"# select_table.on_click(click, column='A') "
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -1064,7 +1090,7 @@
"source": [
"## Buttons\n",
"\n",
"If you want to trigger custom actions by clicking on a table cell you may declare a set of `buttons` that are rendered in columns after all the data columns. To respond to button clicks you can register a callback using the `on_button_click` method:"
"If you want to trigger custom actions by clicking on a table cell you may declare a set of `buttons` that are rendered in columns after all the data columns. To respond to button clicks you can register a callback using the general `on_click` method:"
]
},
{
Expand Down
3 changes: 2 additions & 1 deletion panel/models/tabulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ class CellClickEvent(ModelEvent):

event_name = 'cell-click'

def __init__(self, model, column, row):
def __init__(self, model, column, row, value=None):
self.column = column
self.row = row
self.value = value
super().__init__(model=model)


Expand Down
4 changes: 4 additions & 0 deletions panel/models/tabulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,10 @@ export class DataTabulatorView extends PanelHTMLBoxView {
tab_column.headerFilterParams = tab_column.editorParams
}
}
tab_column.cellClick = (_: any, cell: any) => {
const index = cell._cell.row.data._index;
this.model.trigger_event(new CellClickEvent(column.field, index))
}
if (config_columns == null)
columns.push(tab_column)
}
Expand Down
37 changes: 29 additions & 8 deletions panel/widgets/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -958,16 +958,14 @@ def _cleanup(self, root):
super()._cleanup(root)

def _process_event(self, event):
if self.pagination == 'remote':
nrows = self.page_size
event.row = (self.page-1)*nrows
if event.column not in self.buttons:
event.value = self._processed[event.column].iloc[event.row]
if event.event_name == 'table-edit':
if self.pagination:
nrows = self.page_size
offset = (self.page-1)*nrows
else:
offset = 0
row = offset + event.row
if self._old is not None:
event.old = self._old[event.column].iloc[row]
event.value = self._processed[event.column].iloc[row]
event.old = self._old[event.column].iloc[event.row]
for cb in self._on_edit_callbacks:
cb(event)
else:
Expand Down Expand Up @@ -1543,6 +1541,24 @@ def on_edit(self, callback):
"""
self._on_edit_callbacks.append(callback)

def on_click(self, callback, column=None):
"""
Register a callback to be executed when any cell is clicked.
The callback is given a CellClickEvent declaring the column
and row of the cell that was clicked.

Arguments
---------
callback: (callable)
The callback to run on edit events.
column: (str)
Optional argument restricting the callback to a specific
column.
"""
if column not in self._on_click_callbacks:
self._on_click_callbacks[column] = []
self._on_click_callbacks[column].append(callback)

def on_button_click(self, callback, column=None):
"""
Register a callback to be executed when a cell corresponding
Expand All @@ -1558,6 +1574,11 @@ def on_button_click(self, callback, column=None):
Optional argument restricting the callback to a specific
column.
"""
self.param.warning(
"DeprecationWarning: The on_button_click callbacks will be "
"removed before the 0.13.0 release, please use the generic "
"on_click callback instead."
)
if column not in self._on_click_callbacks:
self._on_click_callbacks[column] = []
self._on_click_callbacks[column].append(callback)