Reading Dash Table

Hi I am trying to create an interactive dash table where I can list an array of xyz positions and the motors should move to those positions row-by-row after I press an execute button (see image) output

For now, I want to see if I can mimic this by printing out the rows one by one after I press the execute button. This is my html input:

params = ['x', 'y', 'z']

...

html.Div(
            [
                dash_table.DataTable(
                    id='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, 3)
                    ],
                    style_cell_conditional=[
                        {'if': {'column_id': 'Model'},
                         'width': '100px'},
                        {'if': {'column_id': 'x'},
                         'width': '100px'},
                        {'if': {'column_id': 'y'},
                         'width': '100px'},
                        {'if': {'column_id': 'z'},
                         'width': '100px'},
                    ],
                    n_fixed_rows=1,
                    editable=True,
                ),
            ], className="six columns"
        ),
        html.Button(
            'Execute',
            id="run",
            className="one columns",
            n_clicks=0,
            style={
                # "float": "right",
                "display": "flex",
                "justify-content": "center",
                "align-items": "center",
                "marginLeft": "2%",
                "marginTop": "0%",
            },
        ),
        # Placeholder Divs
        html.Div(
            [
                html.Div(id="table-output"),
                html.Div(id="run-output"),                
            ],
        ),

and this is my app callback:

@app.callback(
    Output("run-output", "children"),
    [Input("run", "n_clicks"),
     Input("table", "data"),
     Input("table", "columns")]
)
def run_spots(n_clicks, rows, cols):
    df = pd.DataFrame(rows, cols=[c['name'] for c in cols])

    if n_clicks >= 1:
            return [col['name'], df[col['id']]] for col in cols]

As you can see I am not too sure how to exactly do this part. Can anyone please advise?

Cheers, H

I guess I should clarify that I only want to update table e.g. all rows and columns, and read and return the values row-by-row only after pressing the execute button.

The example here automatically reads the instant I input a number in the fields.

Use State instead of Input to get the data into the function. Then the data will only be read when the button is pushed. :+1:

@app.callback(
    Output("run-output", "children"),
    [Input("run", "n_clicks")],
    [State("table", "data"),
     State("table", "columns")]
)
def run_spots(n_clicks, rows, cols):
    df = pd.DataFrame(rows, cols=[c['name'] for c in cols])

    if n_clicks >= 1:
            return [col['name'], df[col['id']]] for col in cols]

Hi

if I run this the following error comes up:

Traceback (most recent call last):
  File "C:/Users/hwahab/Documents/pyControl/codes/Table_test.py", line 212, in <module>
    State('table', 'columns')]
  File "C:\Users\hwahab\Anaconda3\envs\controller\lib\site-packages\dash\dash.py", line 1018, in callback
    self._validate_callback(output, inputs, state)
  File "C:\Users\hwahab\Anaconda3\envs\controller\lib\site-packages\dash\dash.py", line 654, in _validate_callback
    for i in inputs:
TypeError: 'Input' object is not iterable

Does State not work individual row, col values in a dataframe?

This may be a syntax error, make sure Input is within a list.

Ah okay. my bad, I left the Input out of the list.

Now I get the error in the dataframe

    df = pd.DataFrame(rows, cols=[c['name'] for c in cols])
TypeError: __init__() got an unexpected keyword argument 'cols'

Sorry, I am pretty new to this.

No prob. pd.DataFrame needs columns=... instead of cols=...

Hi Russell

so the app runs without error, but when I click the Execute button the page goes blank.

Any ideas?

Here’s the updated callback:

@app.callback(
    Output('run-output', 'children'),
    [Input("run", "n_clicks")],
    [State('table', 'data'),
     State('table', 'columns')]
)
def run_spots(n_clicks, rows, columns):
    df = pd.DataFrame(rows, columns=[c['name'] for c in columns])

    if n_clicks >= 1:
        return [[col['name'], df[col['id']]] for col in columns]