ipyaggrid icon indicating copy to clipboard operation
ipyaggrid copied to clipboard

get_grid() doesn't work properly when adding/deleting rows (async delayed)

Open gioxc88 opened this issue 1 year ago • 9 comments

Below a simple reproducible example:

  1. I have a function called get_add_delete_row_fn that adds 3 options to the right click context menu for deleting rows and adding rows above or below
  2. The function works correctly on the front end (rows get deleted and added)
  3. When I then call grid.get_grid() and display grid.grid_data_out['grid'] the output is not updated right away (it still shows the data previous to deletion/addition)
  4. If I wait a few seconds and call grid.grid_data_out['grid'] the data is updated correctly.
  5. Also if I rerender the grid, the changes are lost

this is the function to add the the context menu the option for deleting and inserting rows

import pandas as pd
import numpy as np
from ipyaggrid import Grid

def get_add_delete_row_fn(blank_row=None):
    blank_row = blank_row or 'null'
    fn = f'''
        function (params) {{
            let blankRow = {{}};
            params.columnApi.getAllColumns().forEach((column) => {{
              blankRow[column.getColId()] = '';
            }});

            if ({blank_row} !== null) {{ 
               blankRow = {blank_row};
            }};

            // console.log({blank_row});
            // console.log(blankRow);

            return [
              {{
                name: 'Delete Row(s)',
                action: function () {{
                  let selectedRows = params.api.getSelectedRows();
                  // console.log(selectedRows);
                  // let selectedData = selectedNodes.map(node => node.data);
                  params.api.applyTransaction({{ remove: selectedRows }});
                }},
              }},
              {{
                name: "Insert Row Above",
                action: function() {{
                  let newData = blankRow;
                  params.api.applyTransaction({{add: [blankRow], addIndex: params.node.rowIndex}});
                }},
              }},
              {{
                name: "Insert Row Below",
                action: function() {{
                  let newData = blankRow;
                  params.api.applyTransaction({{add: [blankRow], addIndex: params.node.rowIndex + 1}});
                }},
              }},
              'copy',
              'paste',
              'separator',
              // other context items...
            ];
          }}
    '''
    return fn

This is the grid creation

df = pd.DataFrame([{'a': i, 'b': i+1, 'c':i+2} for i in range(10)])
g = Grid(
    grid_data=df,
    grid_options={
        'columnDefs': [{'field': col} for col in df],
        'enableSorting': True,
        'enableFilter': True,
        'enableColResize': True,
        'enableRangeSelection': True,
        'getContextMenuItems': get_add_delete_row_fn(),
        'rowSelection': 'multiple'
    },
    theme='ag-theme-balham',
    show_toggle_edit=True,
    sync_on_edit=True,
)
g

image

Now to reproduce the example could you please:

  1. Delete a few rows (select multiple rows by holding CTRL or SHIFT, then right click and Delete Row(s)) (Tip: if you don't see the menu it's because it's covered by the jupyterlab menu, just scroll with the mouse wheel and it should appear)
  2. Execute the following in a cell:
g.get_grid()
display(g.grid_data_out['grid'])

You will see that the data is not updated, but the cell is executed

image

  1. Now please wait 1 or 2 seconds and execute only this g.grid_data_out['grid'] in another cell. Now the data is updated. image

  2. Finally try to rerender the grid in another cell and you'll see that the changes are lost image

gioxc88 avatar Jul 05 '23 09:07 gioxc88