Few questions regarding AG-Grid

Hi All,
I’m on preparing databes interface with Ag Grid. I’m not a programmer so sorry if You’ll find my questions foolish
I’ve few questions regarding Ag grid itself :

  • is is possible to drag and paste by holding one corner of a cell (like in excel)?
  • how to programm initial sorting when app is loading? I found initial filtering but can’t find initial sorting command
  • how to store app settings for next login (for example different column order for different users?) is it doable on AG Grid level or do I have to program it with other tools?)
  • how to set “enter” as move cursor down, like in excel

and question besides Ag Grid
I’ve callback for cellValueChanged, so whenever I change value in Ag Grid the value is being changed in database, but not for deleting value in numeric columns because app is sending empty string instead deleting value, and this causes en error for numeric column…what should be sql like for deleting numeric values?

Andrzej

Hello @acidkans,

1 - only in enterprise
2 - you can use the columnState or columnDefs to set a default sort.
3 - You can use persistence on the columnState, or you can have a save button that stores the columnState in a db using the page and user as a key.
4 - You need to set the enterMovesDown inside the dashGridOptions
5 - For a number that needs to be blanked, replace it with NULL

Please check the documents, most of these question are addressed in the documents. :slight_smile:

Hi, many thanks
I was looking for these but maybe not thoroughly enough…
"enterMovesDown is not working…

grid = dag.AgGrid(
    id = 'main-table',
    rowData=df_invoicing.to_dict('records'),
    columnDefs= columndefs,
    columnSize="responsiveSizeToFit",
    defaultColDef=defaultColDef,
    style={"height": 1000,"width":"100%"},
    dashGridOptions={"undoRedoCellEditing": True,
                     "rowSelection": "multiple",
                     # "domLayout": "autoHeight",#autoHeight przyznaje wysokośc grida zaleznie od ilości wierszy, tak żeby wszystkie były widzoczne
                     "rowHeight":50,
                     "enableRangeSelection" : True,
                     "enableCellTextSelection": True,},
                        filterModel={'fk_id': {'filterType': 'text', 'type': 'notBlank'},
                    "enterMovesDown" : True
                    }`Preformatted text`
```any idea what isn't it?
once again thanks for helping me

Are you trying to move down after hitting enter and you were editing?

enter keeps me in the same cell but puts me in editing mode…on and off

Hi @acidkans

Like in this example in the docs, also include "enterMovesDownAfterEdit": True

 dashGridOptions={"enterMovesDown": True, "enterMovesDownAfterEdit": True},

To allow consistency with Excel the grid has the following properties:

  • enterMovesDown: Set to True to have Enter key move focus to the cell below if not editing. The default is Enter key starts editing the currently focused cell.
  • enterMovesDownAfterEdit: Set to True to have Enter key move focus to the cell below after Enter is pressed while editing. The default is editing will stop and focus will remain on the editing cell. The example below demonstrates the focus moving down when Enter is pressed.
1 Like

Hey guys, I have a question regarding Dash AG-Grid:

You can trigger a callback when user double clicks a cell by using the “cellDoubleClicked” attribute. This works great.

I am wondering is it possible to trigger a callback when the user clicks an area in the dash ag-grid where there is no data but just empty space? So they’re clicking on the table but not on a specific row?

Thank you

Hi @dsmi90
Not sure what you mean about clicking on empty space… but you can also use cellClicked prop in a callback for a single click as well.

To have a click in the space under the grid, but still in the wrapper, you’d have to be listening to the div wrapper.

This can be done, though it is a little trickier to do. Might also help with ending editing when you don’t want to use the stopEditingWhenCellsLoseFocus or whatever it is called.

Hi,
many thanks, I couldn’t find it in docs…
but anyway after putting both lines in my code it didn’t work but found constrain with other option-
“enableCellTextSelection”.
so to have focus on cell below after clicking Enter enableCellTextSelection must be False…
dashGridOptions={ "undoRedoCellEditing": True, "rowSelection": "multiple", # "domLayout": "autoHeight",#autoHeight przyznaje wysokośc grida zaleznie od ilości wierszy, tak żeby wszystkie były widzoczne "rowHeight":50, "enableRangeSelection" : True, # "enableCellTextSelection": True,}, # filterModel={'fk_id': {'filterType': 'text', 'type': 'notBlank'}, "enterMovesDown" : True, "enterMovesDownAfterEdit": True } )

Hi AnnMarie,
I’d like to come back to “Enter moves down…”
I used code dashGridOptions={"enterMovesDown": True, "enterMovesDownAfterEdit": True}
It works fine until I have to update databe with new values
I would like to use Ag Grid for database management and after edyting database with new values, when callback returns rowData to the layout, cell is loosing focus, so I have to click on it anyway to get it focused again
How can I hold focus on a cell after it’s being updated by dataframe.to_dictionary(‘records’)
couldn’t find any info about it…

@app.callback(
    Output('main-table','rowData',allow_duplicate=True),
    Input('main-table','cellValueChanged'),
    prevent_initial_call = True
)
def print_row_data(cellValueChanged):
    if cellValueChanged is None or len(cellValueChanged) ==0:
        return dash.no_update
    changed_cell_id = cellValueChanged['data']['fk_id']
    changed_cell_new_value = cellValueChanged['value']
    changed_cell_column_name = cellValueChanged['colId']
    changed_cell_row_Id = cellValueChanged['rowId']

    conn = engine.connect()

    try:
        if changed_cell_new_value =="":
            update_statement = f"set search_path to reporting; Update table SET {changed_cell_column_name} = Null WHERE id = {changed_cell_id};"
        else:
            update_statement= f" set search_path to reporting; Update table SET {changed_cell_column_name} = '{changed_cell_new_value}' WHERE id = {changed_cell_id};"
        conn.execute(sql_text(update_statement))
        conn.commit()
        df_invoicing_updated = pd.read_sql_query(con=conn, sql=sql_text(query))
        conn.close()
        return df_invoicing_updated.to_dict('records')

    except Exception as e:
        print("Error when connecting to database:", e)
        conn.close()
        return dash.no_update

When adjusting rowData, the grid is refreshing, you can’t hold the focus. To make it easier, you can use getRowId along with a rowTransaction to make it smoother.

Why are you querying the db table each time you change a value?

Hi Jinnyzor,
thanks for helping me.

as mentioned at the beginning I’m not a programmer thats why many of my lines of code are unprofessional and maybe even wrong from efficiency point of view…but my goal is to prepare app for DB management in my company and keep improving it during time…

I tried to update only dataframe values without refreshing DB but it keeps returning old dataframe values before editing cell, I can’t find the reason why DF is not refreshing…but anyway even with refreshing DF only Grid looses focus…which makes this enterMovesDown option useless…
my DF update code was:

df_invoicing_updated.loc[f'{changed_cell_column_name}'][f'{changed_cell_row_Id}']= changed_cell_new_value,

and full callback as below, but it didn’t give me back DF with new values…

if cellValueChanged is None or len(cellValueChanged) ==0:
    return dash.no_update
changed_cell_id = cellValueChanged['data']['fk_id']
changed_cell_new_value = cellValueChanged['value']
changed_cell_column_name = cellValueChanged['colId']
changed_cell_row_Id = cellValueChanged['rowId']

conn = engine.connect()

try:
    if changed_cell_new_value =="":
        update_statement = sql_text(f"set search_path to reporting; Update fakturowanie_kellner SET {changed_cell_column_name} = Null WHERE id = :changed_cell_id;")
    else:
        update_statement= sql_text(f" set search_path to reporting; Update fakturowanie_kellner  SET {changed_cell_column_name} = :changed_cell_new_value WHERE id = :changed_cell_id;")
    conn.execute(update_statement,{'changed_cell_id' :changed_cell_id,'changed_cell_new_value':changed_cell_new_value})
    conn.commit()
    conn.close()
    df_invoicing_updated.loc[f'{changed_cell_column_name}'][f'{changed_cell_row_Id}']= changed_cell_new_value,
    
    return df_invoicing_updated.to_dict('records')

except Exception as e:
    print("Błąd podczas aktualizacji bazy danych:", e)
    conn.close()
    return dash.no_update

x

The grid should be up to date with what the db is showing, if you don’t need to worry about info changing on the backend from other user interaction.

Basically, you don’t need to bother with returning info from the db because you are using the grid to change it.

Also, you shouldn’t allow for taking direct user variables into sql commands or queries. Lookup SQL injection.

Hi ,
so what do You advise to return from callback function? whenever I put initial DF my new data is gone from the Grid

You don’t need to send anything back to the grid, just return dash.no_update.

…nice…I save some throughput between app and db…
but in certain moment I’d have to update grid…
where do i find documentation regarding good practices for db connection management? did not find any in dash docs
could you recomend any www or documentation?

once again many thanks for advices

Hi,
need your help with understanding Dash (Grid) relation with database…
my database is being edited by many users and 2 different apps…
therefore i need to refresh my grid data somehow (dataframe)…to even data in DB and Grid
since I can’t make it by callback, what would be solution to refresh query to update my grid data?
would anyone point me to any solution?
where should I look for solution?

appreciated any tips
thanx in advance

Hi jinnyzor,
I’d like to come back to topic of updating Ag-Grid connected to Postgress.
I’ve MULTIUSER app which is front end for postgress db which.
I must have fresh data in the grid.
my approaches for synchronizing views for all users were:

  1. update grid whenever value has changed
@callback(
    Output('main-table','rowData',allow_duplicate=True),   #
    Input('main-table','cellValueChanged')
  1. update grid periodically (Interval)
@callback ( Output('main-table','rowData'),
            [Input('store-invoicing','data'),
             Input('interval-refresh-invoicing','data')])

actually both methods do the same…read db write to df and refresh data in the grid…

and both have the same issue, after refreshing Grids’s rowData it rerenders whole grid, so whenever user veiws scrolled grid it sends user back to the top of the grid…thats annoying…
what is the best practice to synchronize data in all users views without having this issue?
I can imaginge that there are some descrete refreshes of the data in the grid…or am I wrong?
second issue is that whenever user logs in, first grid vew is with old data, and after interval refreshes data is sychronized…
this issue is related to df which is source for the grid, in both methods I update the same df…but it seems it’s updating copy of my df not hte right one…
any tips appreciated…

My recommendation is still the same, you should be using rowTransaction to update the grid with new data.

Instead of always pulling all the data, you could keep a timestamp of when data was updated on your db, then each subsequent request (after the initial grid loads), you can only pull updates from the db that have occurred since the last query, obviously you should allow for some latency in your updates. Something like this might work:

df = pd.read_sql_query("select * from table where datemodified > dateadd('m', 3, ?)", con, params=[lastdate])
if !df.empty:
    return {'update': df.to_dict('records')}

If is possible things can get added or remove, then you’ll need to pull the state of your current gird and compare and remove ids accordingly.