Input validation in data table

Hi,

is there a straight forward way how to validate and limit user input in data table? I read the documention related to the topic of Typing into the data table(https://dash.plot.ly/datatable/typing) and it looks possible to accomplish this issue via on_change.action , on_change.failure and validation. I was not able to set the parameters as I wanted.

I have data table with two columns (car, code). Code column is editable and I want to limit the user input to this column to only strings A, B or C. It is possible to use dropdown but in case when data table has higher number of rows it is slow approach. The second variant is that if user type unallowed string the whole row will be colorized into the red and the warning text will appear under the data table.

Thank you :slight_smile:


code:

import dash
import dash_html_components as html
import dash_table
import pandas as pd
from collections import OrderedDict

app = dash.Dash(__name__)

df_typing_formatting = pd.DataFrame(OrderedDict([
    ('car', ['car_1', 'car_2', 'car_3', 'car_4', 'car_5', 'car_6']),
    ('code', ['A', 'A', 'B', 'B', 'C', 'C'])
]))

row=''

app.layout = html.Div([
    dash_table.DataTable(
        id='typing_formatting',
        style_table={
            'maxWidth': '400',
            'color': 'black'
        },
        data=df_typing_formatting.to_dict('rows'),
        editable=True,
        columns=[
        {
            'id': 'car',
            'name': u'car',
            'type': 'text',
            'editable': False
        },
        {
            'id': 'code',
            'name': 'code',
            'type': 'text',
            'on_change': {
                'action': 'coerce',
                'failure': 'reject'
            }
        }],
        style_data_conditional=[
                    {
                    "if": {
                        'filter': 'code != "A" and code != "a" and code != "B" and code != "b" and code != "C" and code != "c"',
                    },
                        "backgroundColor": "#FF0000",             
                        'color': 'white'
                    },

                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "A"'
                    },
                        "backgroundColor": "#2ca02c",             
                        'color': 'white'
                    },

                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "a"'
                    },
                        "backgroundColor": "#2ca02c",             
                        'color': 'white'
                    },
                            
                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "B"'
                        },
                        "backgroundColor": "#efb217",
                        'color': 'white'
                    },

                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "b"'
                        },
                        "backgroundColor": "#efb217",
                        'color': 'white'
                    },
                            
                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "C"'
                    },
                        "backgroundColor": "#d62728",
                        'color': 'white'
                    },
                    
                    {
                    "if": {
                        'column_id':'code',
                        'filter': 'code eq "c"'
                    },
                        "backgroundColor": "#d62728",
                        'color': 'white'
                    }
                    ],
    ),
    html.Div(id = 'warning', children = '')
])

@app.callback(
    dash.dependencies.Output('typing_formatting', 'data'),
    [dash.dependencies.Input('typing_formatting', 'data_timestamp')],
    [dash.dependencies.State('typing_formatting', 'data')])
def update_cstic_code_data_table(timestamp, data):
    
    return data

@app.callback(
    dash.dependencies.Output('warning', 'children'),
    [dash.dependencies.Input('typing_formatting', 'data_timestamp')],
    [dash.dependencies.State('typing_formatting', 'data')])
def warning_cstic_code_data_table(timestamp, data):
    
    print(data)
    row = [data[i]['car'] for i in range(0, len(data)) if data[i]['code'] not in ['A','B','C','a','b','c']]
    
    if len(row)==0:
        children = ''
    elif len(row)==1:
        row = ', '.join(row)
        children = 'The code stored in the row with car value equal to '+row+' is not allowed.'
    elif len(row)>1:
        row = ', '.join(row)
        children = 'The codes stored in the rows with car values equal to '+row+' are not allowed.'
    
    print(children)

    return children



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