preftech / dash-tabulator

Tabulator component for Dash Plotly

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Change events not emitted on data change

emilhe opened this issue · comments

It would be nice, if it was possible to run callbacks when the data is edited by the user. Consider the following example,

import json
import dash
import dash_html_components as html
from dash_tabulator import DashTabulator
from dash.dependencies import Input, Output

# Example data.
columns = ["a", "b", "c"]
dt = DashTabulator(columns=[{"title": c, "field": c, "editor": True} for c in columns],
                   data=[{c: c for c in columns}], id="tabulator")
# Example app.
app = dash.Dash()
app.layout = html.Div([dt, html.Div(id="log")])


@app.callback(Output("log", "children"), [Input("tabulator", "data")])
def on_change(data):
    return json.dumps(data)


if __name__ == "__main__":
    app.run_server(port=8075)

When the user edits the data, nothing happens,

Screenshot from 2020-10-05 13-57-23

EDIT: I guess one would need to listen to

cellEdited={(cell: any) => console.log('cellEdited', cell)}
dataEdited={(newData: any) => console.log('dataEdited', newData)}

Sorry I only saw this now, were you able to get this working with registering callbacks?

Sorry I only saw this now, were you able to get this working with registering callbacks?

I'm not OP, but I'm having the same problem and I'm not able to get it fixed.
Any hint?

@pjaol - I ended up just using the default DataTable for cases where user interactivity was needed. Extending the implementation to include interactivity would be really nice (I like the DashTabulator much better), but I figured it would take too much time to do as compared to the benefits for my current use case.

ok I've added both a cellEdited and dataChanged callback in #5
cellEdited is cut down from what is available in tabulator, as the tabulator version is designed for DOM manipulation and has a lot of circular references that can't get converted to json

These are the values I've pulled from it

edited.column = cell.getField()
edited.initialValue = cell.getInitialValue()
edited.oldValue = cell.getOldValue()
edited.value = cell.getValue()
edited.row = cell.getData()

and you can register a callback with

@app.callback(Output('output', 'children'), [Input('input', 'cellEdited')])

Which will give you the following object in python

{
   'column': 'name', 
   'initialValue': 'Oli Bob', 
   'oldValue': 'Oli Bob', 
   'value': 'Oli Bob13444', 
   'row': {'id': 1, 'name': 'Oli Bob13444', 'age': '12', 'col': 'red', 'dob': ''}
}

For mapping back for say a DB editor ensure you have a unique key in the row
Initial value contains the value that the cell was constructed with
oldValue contains the previous change
value contains the post edit change

For dataChanged similar to above

@app.callback(Output('output', 'children'), [Input('input', 'dataChanged')])

This returns an array of the new data table, be aware this could be a heavy call, use sparingly otherwise you will have a slow webpage.

Going to close, and assume this is working - please let me know if there's still an issue