Ag-Grid component with input support

@PablocFonseca understood, I will keep exploring - just in case anyone is struggling, I worked out how to include dropdown options for cell input like this:

# my_list_of_options = ['Option 1', 'Option 2', 'Option 3']
# gb.configure_column("field_name", editable=True, cellEditor='agSelectCellEditor', cellEditorParams={'values': my_list_of_options })

Separately, have you or anyone else experienced random times where the grid suddenly keeps reloading when a selection is made, even though the grid preferences are as in your examples. For example, have been times where I have reload_data=True and selections do persist after selected, but all of a sudden this now doesn’t work and I have to set reload_data=False. This is a problem because I have a function that saves input from streamlit UI components and is then supposed to reload the grid based on those inputs. Is there another way to do this? Think that’s all my questions, and again, such a great too.

3 Likes

Hi @PablocFonseca, can the current st-aggrid implement a date picker in the cell as the following diagram?

1 Like

Hi… loving this streamlit component! I am having trouble getting back an input change. What am I doing wrong here:

import streamlit as st
import plotly.express as px
from st_aggrid import AgGrid, GridOptionsBuilder, DataReturnMode

df = px.data.iris()

gb = GridOptionsBuilder.from_dataframe(df)
gb.configure_column('sepal_width', editable=True)
grid_options = gb.build()
grid_response = AgGrid(df, gridOptions=grid_options, data_return_mode='AS_INPUT', update_model='MODEL_CHANGE\
D')

df = grid_response['data']
st.write(df)

When I edit a cell in my table I get back and empty dataframe and the error:

ValueError: Value of 'x' is not the name of a column in 'data_frame'. Expected one of [] but received: sepal_width
Traceback:
File "/opt/conda/lib/python3.7/site-packages/streamlit/ScriptRunner.py", line 319, in _run_script
File "/tmp/working/app/app.py", line 51, in <module>
    title=f"Template: {temp}",
File "/opt/conda/lib/python3.7/site-packages/plotly/express/_chart_types.py", line 64, in scatter
    return make_figure(args=locals(), constructor=go.Scatter)
File "/opt/conda/lib/python3.7/site-packages/plotly/express/_core.py", line 1831, in make_figure
    args = build_dataframe(args, constructor)
File "/opt/conda/lib/python3.7/site-packages/plotly/express/_core.py", line 1364, in build_dataframe
    args, wide_mode, var_name, value_name
File "/opt/conda/lib/python3.7/site-packages/plotly/express/_core.py", line 1166, in process_args_into_dataframe
    raise ValueError(err_msg)
1 Like

Hi @PablocFonseca thank you for your awesome work and effort put into this. I like to know if the st_aggrid column can take if conditions.

For example:
if value in CAlc Options == ‘$ / unit’, return df['Yield], else df[‘NIA’]

image

You could use some Js expression in valueGetter in a virtual column (check this example)

I do not know your use case, but i’d calculate everything in python first and use AgGrid to render the final dataframe. Seems easier.

1 Like

Thank you for your reply. The downside of using python first and render through AgGrid is the result column is not responsive based on the changes in Calc Options. I’ve look at the example scripts, it helps with the my calculation tab, but how would you use the valueGetter to have if conditions. Thank you very much.

Hi again @PablocFonseca, there still appears to be a bug with this somewhere surrounding row selection - sometimes, when I have selection enabled and reload_data=True, and select a row or edit a cell, Streamlit shows “Running…” in the top right corner and removes the selection or content you’ve edited.

loaded_data = pd.DataFrame({'Fruit':["Grape", "Apple"], 'Vegetable':["Carrot", "Green Bean"]})
gb = GridOptionsBuilder.from_dataframe(loaded_data)

gb.configure_default_column(groupable=True, value=True, enableRowGroup=True, aggFunc='sum', editable=True)

gb.configure_selection('multiple', use_checkbox=False, groupSelectsChildren=True, groupSelectsFiltered=True)
gb.configure_pagination(enabled=True)
gridOptions = gb.build()

main_grid_response = AgGrid(
    loaded_data,
    gridOptions=gridOptions
    height=400,
    width='100%',
    data_return_mode=DataReturnMode.AS_INPUT
    update_mode=GridUpdateMode.MODEL_CHANGED
    fit_columns_on_grid_load=True, # automatically fits all columns to be displayed in the grid in one view
    allow_unsafe_jscode=True, #Set it to True to allow jsfunction to be injected
    reload_data=True,
    enable_enterprise_modules=True
    key='main_grid',
    )

Is there any way to solve this temperamental issue if I want this grid to update based on user input? For example, the idea is that a user will enter information in a form below, press submit, and this information should end up in the grid at the top, without the grid re-initialising. Thanks

can you add a customPercentFormat simular to customCurrencyFormat?

1 Like

Did anyone manage to figure this one out? I’m have trouble getting the JS function for the DatePicker in the app. Tried a lot of different methods (also tried including it inside the i-frame sinds it’s sandboxed) but keep running into the AgGrid “editor not registered” error.

1 Like

@PablocFonseca Thank you so much for the great component. I am not able to find any other component which just handles the selection of rows. I am trying for that purpose only.
I have one issue when I am using AgGrid on server hosted script 60-70% of time
“Your app is having trouble loading the st_aggrid.agGrid component.” this message came.
Please help me out in how can I make it more stable so that it will load all the time.
I am using this configure:
grid_response =AgGrid(df,
gridOptions=gridOptions,
update_mode=update_mode_value,
width=‘70%’,
fit_columns_on_grid_load=True,
# enable_enterprise_modules=True,
allow_unsafe_jscode=True,reload_data=False)

@PablocFonseca, is it possible to apply a dark theme to the grid? I tried looking thru the AG Grid documentation on themes but couldn’t figure out how to use it. Thanks!

Hi @PablocFonseca - thanks so much for developing st_aggrid!

I started using streamlit version 0.84.0 today, and unfortunately there seems to be an incompatibility with the st_aggrid component. If I try to apply a filter in the interactive grid, I get an error: "TypeError: string indices must be integers". Rolling streamlit back to version 0.83 solved the issue.

I used the following function to generate the datatable. Has anyone else experienced this?

from st_aggrid import AgGrid, GridOptionsBuilder, DataReturnMode, GridUpdateMode

def interactive_datatable(df):
    '''    
    Use st_aggrid to show well table in GUI with interactive sorting and filtering options.
    
    df: input dataframe
    
    Returns: dataframe of AgGrid output (including filtering via GUI)
    '''
    #set up aggrid display/interactivity options
    gb = GridOptionsBuilder.from_dataframe(df)
    gb.configure_default_column(groupable=True, value=True, enableRowGroup=True, aggFunc='sum', editable=False)
    gridOptions = gb.build()
    
    #set up data return/update modes
    return_mode_value = DataReturnMode.__members__['FILTERED_AND_SORTED']
    update_mode_value = GridUpdateMode.__members__['FILTERING_CHANGED']
    
    data_return_mode = return_mode_value
                       
    grid_data = AgGrid(df, 
                        gridOptions=gridOptions,
                        width='100%',
                        data_return_mode=return_mode_value,
                        update_mode=update_mode_value)
    
    grid_data_df = pd.DataFrame(grid_data['data'])
    
    return grid_data_df

I had just found the same problem and posted about it.
There is an error already when selecting or editing a cell, even without any other logic in the app.
I tried the demo and this error appearing almost in any grid.

@maajdl I got a response from @andfanilo in this thread on the issue - the streamlit team is already working on a fix :slight_smile:

Hi! For some reasons, while displaying data frame in the input grid (editing mode), some of the columns appear empty and thus cannot be edited. To be precise, 2 columns with float values and 1 with integers are always empty, although in the original data frame they are not

This is especially strange, because other columns with floats, integers and dates in the same data frame are completely fine (they are displayed/can be edited). The code is simple:

grid_return = AgGrid(df, editable=True, reload_data=False)

What could be the source of the problem? Thanks!

@PablocFonseca Thank you so much for this fantastic invention. Just wondering is there any limitation in number of rows displaying. Im getting “RuntimeError: Data of size 50.7MB exceeds write limit of 50.0MB” error even though its around 6 MB. But it has 11000 rows. Any thoughts on this?

Hi @dxz6228 Any luck with getting selected rows? Im also having same sure. Not sure what is the solution for it. :frowning:

@rchamila @dxz6228 Don’t know if it’s still relevant to you, but I am able to get rows selection work via the below snippet

def display_table(df: pd.DataFrame) -> AgGrid:
    # Configure AgGrid options
    gb = GridOptionsBuilder.from_dataframe(df)
    gb.configure_selection('single')
    return AgGrid(
        df,
        gridOptions=gb.build(),
        # this override the default VALUE_CHANGED
        update_mode=GridUpdateMode.MODEL_CHANGED
        )

Hope this helps! :muscle:

2 Likes

Thansk @sis , Yeah it was helpful and managed to fix the issue with row selected. But I just want to delete these selected rows and display the updated table. Any thoughts on how to do that?

@rchamila a possible solution to your case is given by the below snippet (consider that I am no expert in neither AG Grid nor streamlit-aggrid components, so maybe some implementations can be improved)

It works for both single and multiple rows selection.

Snippet
import string

import numpy as np
import pandas as pd
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder, GridUpdateMode

st.set_page_config(layout='wide')


def display_table(df: pd.DataFrame, selection: str) -> AgGrid:
    # Configure AgGrid options
    gb = GridOptionsBuilder.from_dataframe(df)
    gb.configure_selection(selection)
    st.write(f"Dataframe shape: {df.shape}")
    return AgGrid(
        df,
        gridOptions=gb.build(),
        # this override the default VALUE_CHANGED
        update_mode=GridUpdateMode.MODEL_CHANGED
    )


# Define dummy data
rng = np.random.default_rng(2021)
N_SAMPLES = 100
N_FEATURES = 10
df = pd.DataFrame(rng.integers(0, N_SAMPLES, size=(
    N_SAMPLES, N_FEATURES)), columns=list(string.ascii_uppercase[:N_FEATURES]))

cols = st.beta_columns(2)

with cols[0]:

    st.markdown('# 🠔 Before')

    # Display AgGrid from data and write response
    st.markdown("### 1️⃣ Let's display dummy data through AgGrid")
    selection = st.radio('Selection mode', ['single', 'multiple'])
    response = display_table(df, selection=selection)

    st.markdown(
        "### 2️⃣ AgGrid response contains `data` (original df) and `selected_rows`")
    for k, v in response.items():
        st.write(k, v)

with cols[1]:

    st.markdown('# 🠖 After')

    # Retrieve selected rows indices
    st.markdown(
        "### 3️⃣ From selected rows we can obtain dataframe indices to drop")
    data = response['data'].to_dict(orient='records')
    indices = [data.index(row) for row in response['selected_rows']]
    st.write(f"Selected rows are located at indices: {indices}")

    # Use retrieved indices to remove corresponding rows from dataframe
    st.markdown(
        "### 4️⃣ Display the updated dataframe where rows have been removed")
    _df = df.drop(indices, axis=0)
    st.write(f"Dataframe shape: {_df.shape}")
    AgGrid(_df)
3 Likes