# Remove rows from Tabulator widget

**URL:** <https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094>\
**Category:** Panel\
**Tags:** tabulator\
**Created:** [September 26, 2023, 10:22pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094 "2023-09-26T22:22:10Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [September 26, 2023, 10:22pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/1 "2023-09-26T22:22:11Z")

</div>

Hi all,  
I’m using panel.widget.Tabulator for the first time. It’s super useful widget and very versatile.  
I wish there was more documents and examples for it.  
I need to add a trash can column to the table and allow user to delete a row when they click on the trash can for that row.  
Getting idea from [here](https://discourse.holoviz.org/t/catch-cellclick-event-in-table/3544/2), I wrote following code:

```auto
# https://discourse.holoviz.org/t/catch-cellclick-event-in-table/3544/2
import panel as pn
import pandas as pd

pn.extension("tabulator")

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=['a', 'b', 'c'])
tbl = pn.widgets.Tabulator(df, selectable=True, buttons={"Trash": "<i class='fa fa-trash'></i>"}, disabled=True,)
 
def update_selection(event):
    tbl.value=tbl.value.iloc[list(set(tbl.value.index)-set(tbl.selection))]
    return event

update_selection=pn.bind(update_selection, tbl.param.selection)

pn.Column(tbl, update_selection).servable()

```

1. When user clicks anywhere in a row, that row will be selected. I need to restrict that to clicking on the trash can only.
2. When user clicks a.k.a selects the row, it will be removed from tbl.value but the table will show as before  
 ![image](https://discourse.holoviz.org/uploads/default/original/2X/7/7a8b4aeb3316d5cbad6ad8083fd1e812532c8e71.png)

What am I missing?  
Any tip is appreciated.

---

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [September 26, 2023, 11:39pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/2 "2023-09-26T23:39:13Z")

</div>

I found following in the documents, but I still cannot get it working.

| on\_click(self, callback: ‘Callable[[CellClickEvent], None]’, column: ‘Optional[str]’ = 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. |

---

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [September 26, 2023, 11:51pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/3 "2023-09-26T23:51:16Z")

</div>

1. I think the first issue can be resolved by passing column=‘Trash’ to on\_click()

---

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [September 28, 2023, 12:03am UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/4 "2023-09-28T00:03:50Z")

</div>

With a little bit of hacking, I made it work:

```auto
import panel as pn
import pandas as pd
pn.extension("tabulator")

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=['a', 'b', 'c'])
tbl = pn.widgets.Tabulator(df.copy(), selectable=True, buttons={"Trash": "<i class='fa fa-trash'></i>"}, disabled=True)
 
def delete_selected_row(event):
    tbl.value=tbl.value.drop(tbl.selection, inplace=False) 
    tbl.value.reset_index(inplace=True, drop=True)
    tbl.value=tbl.value.iloc[:]
    return 

tbl.on_click(delete_selected_row, column='Trash') 

pn.Column(tbl).servable()

```

---

<div class="post-metadata">

**Author:** ![nik](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://discourse.holoviz.org/u/nik)\
**Post date:** [November 16, 2023, 12:56pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/5 "2023-11-16T12:56:48Z")

</div>

Thanks for the solution, Mana. Works for me too!

Any way we can have below 3 functionalities?

1. What you showed about deleting a row
2. Adding a row
3. Editing a cell in a row/column

I am quite new to Panel so learning along the way!

---

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [November 16, 2023, 8:25pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/6 "2023-11-16T20:25:24Z")

</div>

Hi Nik,  
I’m glad it helped.

1. The solution is above.
2. I believe you can patch the tabulator with new dataset.
3. I think by default you can edit cells. You can turn it off though.

You may find following helpful:

```auto
import holoviews as hv
import panel as pn
hv.help(pn.widgets.Tabulator)

```

---

<div class="post-metadata">

**Author:** ![nik](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://discourse.holoviz.org/u/nik)\
**Post date:** [November 17, 2023, 9:14am UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/7 "2023-11-17T09:14:45Z")

</div>

Thanks Mana. I have been following the Tabulator documentation, will look more into that.  
Regarding point 3, yes, that is true. Just with the above solution, it is not possible to edit the table as the whole row is selected for deletion. If there is a workaround, please share, else I will figure it out. Thanks in advance!

---

<div class="post-metadata">

**Author:** ![nik](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/n/6de8d8/32.png) [@nik](https://discourse.holoviz.org/u/nik)\
**Post date:** [November 17, 2023, 11:37am UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/8 "2023-11-17T11:37:28Z")

</div>

Ah got it. I had to set “disabled=False” in tbl = pn.widgets.Tabulator() call. So now both editing and removing a row works!  
I will figure out how to add a row dynamically to an existing table (just like you did to remove a row).

---

<div class="post-metadata">

**Author:** ![Mana](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@Mana](https://discourse.holoviz.org/u/Mana)\
**Post date:** [November 22, 2023, 9:40pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/9 "2023-11-22T21:40:48Z")

</div>

I just saw your follow up question. I’m glad you figured it out.

---

<div class="post-metadata">

**Author:** ![vpoduri](https://discourse.holoviz.org/letter_avatar_proxy/v4/letter/v/da6949/32.png) [@vpoduri](https://discourse.holoviz.org/u/vpoduri)\
**Post date:** [August 7, 2024, 7:58pm UTC](https://discourse.holoviz.org/t/remove-rows-from-tabulator-widget/6094/10 "2024-08-07T19:58:00Z")

</div>

Very nice solution. There’s one little limitation that can easily be fixed. If you click directly on the trash icon (without highlighting the row) nothing happens. This can be fixed by changing the function slightly as follows:

```auto
def delete_selected_row(event):
        tbl.value=tbl.value.drop(event.row) 
    return 

```
