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

[Coming soon] Allow dataframe rows to be selectable and trigger a function in Python code #688

Closed
timforr opened this issue Nov 14, 2019 · 44 comments · Fixed by #8411
Closed
Labels
feature:st.dataframe status:in-progress We're on it! type:enhancement Requests for feature enhancements or new features

Comments

@timforr
Copy link

timforr commented Nov 14, 2019

Problem

I have a st.table displaying search results. I want to be able to click on a specific row (or select several rows) and have that trigger an event in Python to update the page.

Solution

MVP: Table rows are clickable and trigger a custom event

Possible additions: What are other things that could be added to the MVP over time to make it better?

Preferred solution: More fully-featured solution similar to DTTables where we can specify custom table styling, embed objects like images in to table cells, select multiple rows or cells, etc.


Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.

If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.

@timforr timforr added the type:enhancement Requests for feature enhancements or new features label Nov 14, 2019
@nthmost
Copy link
Contributor

nthmost commented Nov 18, 2019

Hi @timforr -- Thanks for the feature request! This seems like a natural progression for Streamlit, pending some conversation within the team of course.

@chkoar
Copy link

chkoar commented Mar 30, 2020

Do we have an update on this?

@ajhayes83
Copy link

Yes this functionality would be very extremely useful! I would be keen to know if there is an update . Thanks!

@dennysemko
Copy link

dennysemko commented Apr 19, 2021

I have found myself multiple times over the past year needing this -- I am surprised it is still not implemented!

Something as easy as
clicks row in st.dataframe or st.table
and
receives back the index of the row in the DataFrame

@usapkota
Copy link

Is there any workaround until this enhancement is completed?

@anmol1ratn
Copy link

Any update on this? It would be really useful to be able to click on a specific cell/row and have that trigger an event in Python to update the page.

@fplanque
Copy link

I need this too.

Just a simple on_click event and a way to get the line index would already do wonders !

(Checkboxes on each row would also be an alternative, though in my case I don't need multiselect)

@sfc-gh-shsharma
Copy link

This would unlock a lot of interesting use cases. Typically data is presented in a table. Being able to click would enable pivoting views which is common operation on data.

@luca-serra
Copy link

Hi all, any update on this?
This feature would enable to do so many things with Streamlit!
Looking forward to it.

@jrieke
Copy link
Collaborator

jrieke commented Feb 10, 2023

We're working on this at the moment. No concrete launch data but we should have something during the next few months!

@jrieke jrieke added the status:in-progress We're on it! label Feb 10, 2023
@jace-parkinson
Copy link

jace-parkinson commented Mar 3, 2023

Might be able to use newly added feature to cover this issue.
https://blog.streamlit.io/editable-dataframes-are-here/

@fplanque
Copy link

fplanque commented Mar 3, 2023

Newly added feature should be able to cover this issue.
https://blog.streamlit.io/editable-dataframes-are-here/

How does editing cells in the table allow to react to a clic or to know which row has been selected?

These are different use cases.

@jace-parkinson
Copy link

jace-parkinson commented Mar 4, 2023

Newly added feature should be able to cover this issue.
https://blog.streamlit.io/editable-dataframes-are-here/

How does editing cells in the table allow to react to a clic or to know which row has been selected?

These are different use cases.

Yes, true. Based on examples in https://docs.streamlit.io/library/advanced-features/dataframes?ref=streamlit it seems possible using the session state (though maybe not yet straight forward). If not, the Next Up section in the original link states a more straight forward way to do this should be here soon:

"We have a bunch of new features for st.dataframe and st.experimental_data_editor in the pipeline for the next few months: showing images, clickable URLs in tables, letting the users select rows, and more."

@LukasMasuch LukasMasuch changed the title Allow table rows to be clickable and trigger a function in Python code Allow dataframe rows to be selectable and trigger a function in Python code Jun 4, 2023
@LukasMasuch
Copy link
Collaborator

LukasMasuch commented Jun 4, 2023

We have paused the work on a row selection feature temporarily but will get back to finishing implementing this soon. In the meantime, there is a good workaround with the latest Streamlit update (1.23) to implement a row selection via a checkbox column:

import streamlit as st
import numpy as np
import pandas as pd

df = pd.DataFrame(
    {
        "Animal": ["Lion", "Elephant", "Giraffe", "Monkey", "Zebra"],
        "Class": ["Mammal", "Mammal", "Mammal", "Mammal", "Mammal"],
        "Habitat": ["Savanna", "Forest", "Savanna", "Forest", "Savanna"],
        "Lifespan (years)": [15, 60, 25, 20, 25],
        "Average weight (kg)": [190, 5000, 800, 10, 350],
    }
)


def dataframe_with_selections(df):
    df_with_selections = df.copy()
    df_with_selections.insert(0, "Select", False)
    edited_df = st.data_editor(
        df_with_selections,
        hide_index=True,
        column_config={"Select": st.column_config.CheckboxColumn(required=True)},
        disabled=df.columns,
    )
    selected_indices = list(np.where(edited_df.Select)[0])
    selected_rows = df[edited_df.Select]
    return {"selected_rows_indices": selected_indices, "selected_rows": selected_rows}


selection = dataframe_with_selections(df)
st.write("Your selection:")
st.write(selection)
image

@ymbender
Copy link

Hi,
i would really appreciate to have some callback or just some way to allow updating a separate text field based on the selection made in the dataframe (where the workaround with the selection column is not applicable). Really looking forward to have this.
In general having more "click events" for Streamlit components would really help in many cases (already missed that for tabs component and some other cases).

@jrieke
Copy link
Collaborator

jrieke commented Apr 8, 2024

We just finished a very rough prototype for dataframe selections: https://dataframe-row-selections.streamlit.app/

Feel free to give it a try but note that it's still under active development, so things might and will change! Let me know if you have any feedback.

For a broader picture on selection events, see my comment here.

@LukasMasuch LukasMasuch changed the title Allow dataframe rows to be selectable and trigger a function in Python code [Coming soon] Allow dataframe rows to be selectable and trigger a function in Python code Apr 10, 2024
@jrieke jrieke added status:in-progress We're on it! and removed status:likely Will probably implement but no timeline yet labels Apr 17, 2024
@jrieke jrieke pinned this issue Apr 17, 2024
@jrieke
Copy link
Collaborator

jrieke commented Apr 17, 2024

Quick update: we're quite advanced on the prototype I posted above, as well as on the API discussions. We're currently planning to release dataframe selections for both rows + columns sometime in May or early June mid May. It might still change a bit, though, as we're finalizing our release schedule for the next few months. I'll post some more details on the API soon!

LukasMasuch added a commit that referenced this issue May 13, 2024
## Describe your changes

This PR adds row and column selection support to `st.dataframe`. It can
be used like this:

```python
selection = st.dataframe(
    df,
    on_select="rerun",
    selection_mode="single-row"
)
```

- [Demo App](https://dataframe-row-selections.streamlit.app/)


https://github.com/streamlit/streamlit/assets/2852129/f3ff476a-0bd0-4b82-bc97-6bda3a3be98c

## GitHub Issue Link (if applicable)

- Closes #688
- Closes #7134
- #455
- #8319

## Testing Plan

- Added unit tests
- Added e2e tests (see #8634)

```[tasklist]
### e2e tests
- [x] Single row/column selection
- [x] Multi row/column selection
- [x] Mixed selections
- [x] Screenshot of a dataframe with multiple selections
- [x] Clear selections via toolbar
- [x] Clear selections via escape
- [x] Select all rows in multi-row selection via top checkbox
- [x] Optional: Test drag and drop selection
- [x] Optional: Test shift selections
- [x] Optional: Test selections in form
- [x] Have some test cases work with session state and others with return value
- [x] Add a test case validating that the callback gets called
``` 


---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this
project are made under the Apache 2.0 license.

---------

Co-authored-by: Benjamin Räthlein <benjamin.raethlein@gmail.com>
@LukasMasuch
Copy link
Collaborator

LukasMasuch commented May 13, 2024

We will release row & column selections for st.dataframe in the 1.35 release. You can activate selections via on_select and configure it via selection_mode, e.g.:

selection = st.dataframe(df, on_select="rerun", selection_mode="single-row")

Or for multi-row & column selections:

selection = st.dataframe(df, on_select="rerun", selection_mode=("multi-row", "multi-column"))

You can try it out in this demo.

@LukasMasuch LukasMasuch unpinned this issue May 14, 2024
@chrispy-snps
Copy link

@LukasMasuch - thanks for the demo, this will be great for our application!

@rutuja1409
Copy link

We will release row & column selections for st.dataframe in the 1.35 release. You can activate selections via on_select and configure it via selection_mode, e.g.:

selection = st.dataframe(df, on_select="rerun", selection_mode="single-row")

Or for multi-row & column selections:

selection = st.dataframe(df, on_select="rerun", selection_mode=("multi-row", "multi-column"))

You can try it out in this demo.

Thank you soo much for this update. @LukasMasuch can you let us know when streamlit is planning to release version 1.35? It will be very helpful.

@LukasMasuch
Copy link
Collaborator

@rutuja1409 Probably today or tomorrow :)

@pierreb-met
Copy link

Hey, thank you so much @LukasMasuch for this nice addition!! 👏
I was until now using streamlig-aggrid to handle dataframe row selection, and I'm super glad it's now natively handled by Streamlit 😄

Small question: is there a way to pre-select a row before the dataframe is initially rendered? In my usecase, a specific query parameter can be provided in order to pre select a row when accessing the page. This was possible with streamlit Aggrid (example here).

I was wondering if there was a trick to do the same with st.dataframe? 🙂
Kudos to you!

@LukasMasuch
Copy link
Collaborator

@pierreb-met this is not yet possible, but it would be a reasonable change 👍 It would be awesome if you could create a feature request for this.

@rutuja1409
Copy link

rutuja1409 commented May 28, 2024

@rutuja1409 Probably today or tomorrow :)

Hey @LukasMasuch Thank you for the new version. I tried it, and have a question. So its working fine when I select a row and it displays at the bottom.

But consider I have an selectbox prior, and then based on the value the data is displayed, however the index gets reset from 0 while displaying the rows selected.

Here you can see the index is 2, but the on-select functionality start the index from 0 on filtered dataframe.
Can you help me out here ?

@LukasMasuch
Copy link
Collaborator

LukasMasuch commented May 28, 2024

@rutuja1409 The returned list in rows are positional indices, and not the row index. You can use this with the methods that work on the integer position: e.g. iat or iloc on the filtered dataframe.

@pkonduri
Copy link

@LukasMasuch I'm working on integrating this change. One issue is that this selectable checkbox column has no header/label, so it's not obvious to users that cells in that column can be selected.

Is there any way to add a column label for this?

@LukasMasuch
Copy link
Collaborator

@pkonduri there isn't a way yet to set a header label for the selection column :(

@pkonduri
Copy link

@LukasMasuch thanks for the response. Would be great if this small change could be added as a quick follow up to this task. Especially for public facing apps, users may not realize that the column is meant to be selectable, unless they accidentally hover over the cells.

@LukasMasuch
Copy link
Collaborator

@pkonduri it will probably take a bit more work to address this. Another solution might be to always show the checkboxes as suggested here: #8941

@pkonduri
Copy link

pkonduri commented Jun 19, 2024

@LukasMasuch while both solutions (adding the option for a column header, and outlining the checkboxes as suggested in #8941 ) help achieve clarity that the cells are selectable, there are subtle reasons why one may choose one option over the other.

  1. With a column header, the intent is far more clear. In my case, if a user were to click on a checkbox cell, the chart associated with the stock contained in that row will show up. So labeling the column with show chart makes the intent much more clear.

  2. If the app conveys in other ways why the user should be selecting a cell, then just a checkbox outline is sufficient.

I think supporting both options makes sense. But at the very least, offering the ability to add a label to the checkbox column sounds more intuitive to me. This way, this column is not treated any differently than other columns. Ideally it will mimic the functionality we find in st.column_config.CheckboxColumn for st.data_editor

@C4ORT
Copy link

C4ORT commented Jun 27, 2024

I have a problem with linking on_select to an ID that is in the database
Let me explain: there is an application that searches for data from a database. When information lines are displayed, you can select one of the presented lines. BUT the on_select keys are numbered sequentially from 0 when rendered, and the IDs may be different after sorting by search (for example: 0,3,8,13..)
Any ideas on how to fix this?

@LukasMasuch
Copy link
Collaborator

The IDs are the positional indices and are expected to always map to the row position in the input dataset.

and the IDs may be different after sorting by search

Do you mean sorting on the frontend / UI or sorting the dataframe on the backend?

@C4ORT
Copy link

C4ORT commented Jun 28, 2024

I have a problem with data_editor and column_config
I want to select one row, as can be done in a dataframe (on_select)
It_select could not be used due to indexing, which does not match the indexing in the database after sorting, and the lack of keys in the blocks (I can’t get the data of the selected row)
That’s why I came to the data_editor and came across the problem that it’s impossible to make a single-row here
I tried to find how to reset checkboxes in checkboxColumn, reload a page fragment
I didn't find anything working
can you give me some advice?

@LukasMasuch
Copy link
Collaborator

which does not match the indexing in the database after sorting, and the lack of keys in the blocks(I can’t get the data of the selected row)

The positional index with on_select matches the positional index of the row of the data that you provide with st.dataframe. You should be able to determine a relevant row key using this positional index applied to the input data.

@C4ORT
Copy link

C4ORT commented Jul 1, 2024

Thanks you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature:st.dataframe status:in-progress We're on it! type:enhancement Requests for feature enhancements or new features
Projects
None yet
Development

Successfully merging a pull request may close this issue.