Black Lives Matter. Please consider donating to Black Girls Code today.

Focus jumps from first DataTable to second in a strange way

I have two tables next to each other.
The user is supposed to input words in each of them.
The callback function uses both text lists as separate inputs, and outputs something based on the two.

After entering something to the first table, and when I click on the following cell, the focus jumps to the second table.
Here is the code that I’m having this issue with:

import json
import dash
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div([
                html.Div([
                    dt.DataTable(id='products_table',
                    editable=True,
                    rows=[{'': ''} for num in range(10)],
                    columns=['Products']),
                    ], style={'width': '48%', 'display': 'inline-block'}),
                html.Div([
                    dt.DataTable(id='words_table',
                    editable=True,
                    rows=[{'': ''} for num in range(10)],
                    columns=['Words']),
            ], style={'width': '48%', 'display': 'inline-block', 'float': 'right'}),
                html.Div(id='output_df')    
])

@app.callback(Output('output_df', 'children'),
             [Input('products_table', 'rows'), 
              Input('words_table', 'rows')])
def generate_kw_df(products, words, match_types=['Exact', 'Phrase'], campaign_name='Campaign'):
    product_list = list(set([d.get('Products').strip() for d in products if 'Products' in d]))
    word_list = list(set([d.get('Words').strip() for d in words if 'Words' in d]))
    return json.dumps(list(zip(product_list, word_list))) 


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

Ugh yeah, this is annoying. Unfortunately, this is an issue with the underlying open source datatable that we’re using. We’re fixing this bug (and many more!) by writing our own DataTable component from scratch. It’s not available yet, but it will be this summer.

In the meantime, I’m not sure if there are any workarounds.

Thanks. I might do it with TextArea components and a submit button, to get the user’s inputs. It’s not a massive issue anyway.

Looking forward to the new component!

1 Like

Indeed, TextArea worked for me. It also solved two other problems:
1. Allowing pasting data: This is not straightforward with the DataTable.
2. Making the input unbounded: Ideally this is for an app that helps users generate many keywords and combinations, and it needs to be minimal in size, but also not limited. Again, something that comes for free with TextArea

The prototype is working here: https://advertools.herokuapp.com/ in case you ever need to generate keywords for your AdWords campaign! :smile:

If anyone is still struggling with the focus jumping back to the datatable, one option is to have a button for edit mode vs display mode for your table. Feed your html table with input from your editable table, then make it visibible when your button has n_clicks = even. Conversely, when the n_clicks=odd, make your editable datable visible.