Save input text in Input field inside Dash Editable Datatable without pressing 'Enter' key?

Hi All,
On entering a value in an input field inside an editable datatable, the user must press ‘Enter’ key to save it. Instead, if the user simply clicks outside of this cell, the value provided is not saved and the previous state is visible.

Is there a way by which we can save the input provided when focus moves out without pressing ‘enter’?

HI @AnSohal
This clientside_callback might work:

import dash
from dash import Dash, dash_table, dcc, html
from dash.dependencies import Input, Output, State
import pandas as pd

params = [
    'Weight', 'Torque', 'Width', 'Height',
    'Efficiency', 'Power', 'Displacement'
]

app = Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='our-table',
        columns=(
                [{'id': 'Model', 'name': 'Model'}] +
                [{'id': p, 'name': p} for p in params]
        ),
        data=[
            dict(Model=i, **{param: 0 for param in params})
            for i in range(1, 5)
        ],
        editable=True
    ),
    dcc.Store(id='changed-cell'),

    html.Div(id='filler')
])

# store the row id and column id of the cell that was updated
app.clientside_callback(
    """
    function (input,oldinput) {
        if (oldinput != null) {
            if(JSON.stringify(input) != JSON.stringify(oldinput)) {
                for (i in Object.keys(input)) {
                    newArray = Object.values(input[i])
                    oldArray = Object.values(oldinput[i])
                    if (JSON.stringify(newArray) != JSON.stringify(oldArray)) {
                        entNew = Object.entries(input[i])
                        entOld = Object.entries(oldinput[i])
                        for (const j in entNew) {
                            if (entNew[j][1] != entOld[j][1]) {
                                changeRef = [i, entNew[j][0]] 
                                break        
                            }
                        }
                    }
                }
            }
            return changeRef
        }
    }    
    """,
    Output('changed-cell', 'data'),
    Input('our-table', 'data'),
    State('our-table', 'data_previous')
)


# Update table
@app.callback(
    Output("filler", "children"),
    Input("changed-cell", "data"),
    Input("our-table", "data"),
)
def update_d(cc, tabledata):
    if cc is None:
        return dash.no_update
    else:
        print(f'changed cell: {cc}')
        print(f'Current DataTable: {tabledata}')
    
    return "sample info"


if __name__ == '__main__':
    app.run_server(debug=True)

Hi @ adamschroeder,

Thanks for your reply. Below is my observation.

Input fields in a datatable can be edited in the following two manners:

a. Click on the input cell -

Clicking on the input cell and typing the new value, overwrites the previous value. Simply moving outside of this cell using ‘Enter’ / arrow keys / mouse click, saves the new value provided.

b. Double-click on the input cell -

Double-click the input cell and the previous value can be modified by moving the cursor to the desired location using arrow keys and typing the new value. User must press ‘Enter’ key to save the new value provided. Instead, if the user simply clicks outside of this cell, the new value provided is not saved and the previous value is visible.

Is there a way by which I can rectify the issue reported in second point(that is, Double-click on the input cell)? Any finding can be of great help for my application.

Hi @AnSohal
As far as I know, the DataTable doesn’t have a built-in solution for B.

Hi @adamschroeder
we need to implement this behavior-

b. Double-click on the input cell -
Double-click the input cell and the previous value can be modified by moving the cursor to the desired location using arrow keys and typing the new value. User must press ‘Enter’ key to save the new value provided. Instead, if the user simply clicks outside of this cell, the new value provided is not saved and the previous value is visible.

Can we write any other callback for this? Can you please advise on any approach we can follow? Any idea/leads/opinion will be very helpful.

Hi @anuj_tiwari
I saw point B above. I am not aware of any solution to this kind of behavior you’re looking for. If there is a workaround, I hope someone knows how to build one, but I’m sorry I can’t help you with this customization.