How to set maximun number of columns to appear at same time?

I have a table with 38 columns and I want only 12 columns to appear in one go SO I can avoid scrollX bar,
if the user want to show another column he had to hide first one of the 12 columns
here is my code:

columns=[*[{"name": i, "id": i} for i in dff_table.columns[:3]], *[{"name": j, "id": j, "hideable":True} for j in dff_table.columns[5:14]],
      *[{"name": j, "id": j, "hideable":True, 'editable':True} for j in dff_table.columns[14:]] ], 
hidden_columns = [*dff_table.columns[14:]] 

right now when I select a new column it append the table to be 13 columns and so on,

OR how can I just limit the number of selection in Toggle Columns?

Hello @abdoo,

Yes, can hide columns, via css.

Or you can do as you suggested have a dropdown that has all the column options available, with multi select and use that to build your table.

@app.callback(
Output('myTable','data'),
Output('myTable','columns'),
Input('myDropdown','value')
)
def showColumns(v):
     if v:
          return df[v].to_dict('records'), [{'name':i}, 'id':i} for i in v]

Something like this might be able to work.

If not, you can check out this for css and javascript tricks to expand the data:

1 Like

Hi @jinnyzor thank you for the answer
the dropdown that I have is the default toggle columns
do you know it’s id , otherwise how can refer to it?

Why do you not want scrollX to appear? Is it possible that you just want to scroll inside the table without scrolling in the window?

Could you give a little more detail in the coding aspect, so that I can take a look and what you are trying to accomplish?

table = dash_table.DataTable(
      columns=[*[{"name": i, "id": i} for i in dff_table.columns[:3]], *[{"name": j, "id": j, "hideable":True} for j in dff_table.columns[5:14]],
      *[{"name": j, "id": j, "hideable":True, 'editable':True} for j in dff_table.columns[14:]] ], 
      hidden_columns = [*dff_table.columns[14:]] ,
data=dff_table.to_dict("records"),
      style_header={'whiteSpace': 'normal', 'fontWeight': 'bold', 'backgroundColor': 'white', 'border': '2px solid black'},
      style_cell={ 'border': '1px solid grey' },
      filter_action="native",
      sort_action="native",
       style_data={
        # 'maxWidth':'90vh','width':'90vh',
        'whiteSpace': 'normal',
        'height': 'auto',
        'lineHeight': '15px',
        'color': 'black',
        'backgroundColor': 'white'
      },
      page_size=10,
      ])

yeah, it’s alright to have a scrollX inside the table but I want the width of the dable to be fix: 90% of the width of the page, and the whole page should not have a scrollX

You should be able to do this:

table = dash_table.DataTable(
      columns=[*[{"name": i, "id": i} for i in dff_table.columns[:3]], *[{"name": j, "id": j, "hideable":True} for j in dff_table.columns[5:14]],
      *[{"name": j, "id": j, "hideable":True, 'editable':True} for j in dff_table.columns[14:]] ], 
      hidden_columns = [*dff_table.columns[14:]] ,
data=dff_table.to_dict("records"),
      style_header={'whiteSpace': 'normal', 'fontWeight': 'bold', 'backgroundColor': 'white', 'border': '2px solid black'},
      style_cell={ 'border': '1px solid grey' },
      filter_action="native",
      sort_action="native",
       style_data={
        'maxWidth':'90vw','width':'90vw','overflowX':'auto',
        'whiteSpace': 'normal',
        'height': 'auto',
        'lineHeight': '15px',
        'color': 'black',
        'backgroundColor': 'white'
      },
      page_size=10,
      ])

You can use fixed_columns as well, if you want certain columns to not scroll. (good for row identifiers)

Please note, the width arguments dont do anything if the browser doesnt know what to do with the excess. Thus the need for the overflowX. :slight_smile:

the same behaviour again, keep expanding as add more columns and create a ScrollX for the page, there must be something missing!!

btw when I use fixed_columns={'headers': True, 'data': 3} it only shows the 3 cols, why is that?

@jinnyzor I think this will not work in this cas because the table returned from a callback and adding columns happen by toggle columns which that does not trigger the table callback
SO that’s why when I add 'maxWidth':'90vw','width':'90vw','overflowX':'auto' nothing change, am I right?

if I could limit checkboxes in toggle columns to 13 that will be perfect but I don’t know if it has an id so I can access it by a js function. do you have any idea?

My bad, the maxwidth stuff needed to be in style_table, not style_cell.

Look at this example:

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

app = Dash(__name__)

app.layout = html.Div([

    dash_table.DataTable(
        id='editing-columns',
        columns=[{
            'name': 'Column {}'.format(i),
            'id': 'column-{}'.format(i),
            'hideable': True,
            'renamable': True
        } for i in range(1, 30)],
        data=[
            {'column-{}'.format(i): (j + (i-1)*5) for i in range(1, 30)}
            for j in range(30)
        ],
        fixed_columns={'headers': True, 'data': 3},
        editable=True,
        style_table={
            'maxWidth':'90vw','width':'90vw','overflowX':'auto',
        },
        style_header={'whiteSpace': 'normal', 'fontWeight': 'bold', 'backgroundColor': 'white', 'border': '2px solid black'},
              style_cell={ 'border': '1px solid grey' },
              filter_action="native",
              sort_action="native",
               style_data={
                'whiteSpace': 'normal',
                'height': 'auto',
                'lineHeight': '15px',
                'color': 'black',
                'backgroundColor': 'white'
              },
      page_size=10,
    ),

    dcc.Graph(id='editing-columns-graph')
])


@app.callback(
    Output('editing-columns-graph', 'figure'),
    Input('editing-columns', 'data'),
    Input('editing-columns', 'columns'))
def display_output(rows, columns):
    return {
        'data': [{
            'type': 'heatmap',
            'z': [[row.get(c['id'], None) for c in columns] for row in rows],
            'x': [c['name'] for c in columns]
        }]
    }


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