How can I place text area, datatables and other interactive elements inside Accordion?

In the app.layout below, I am trying to incorporate related, interactive elements like text area and a datatable inside the AccordionItem tags. But I keep receiving this error message:

    )
    ^
SyntaxError: positional argument follows keyword argument

I tried to bold the line in the code pasted below causing the error message, but that does not work. Specifically, it is line numbers 25-26 which I capitalized and separated from the rest of the code with a line space. If I remove the “),” causing the error message, it returns but in reference to the “]” at line number 38-39.

Can someone please explain what is wrong and how to resolve the issue?

The information I find online talks about this error message as it pertains to Python functions, not Dash app layouts. And I am trying to insert a text area into an Accordion item. Perhaps I am not looking in the right place, but I am also not finding the question answered on this forum.

Thank you very much for reviewing my question.

external_stylesheets=[dbc.themes.SUPERHERO]

app = dash.Dash(external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [ html.Br(), 
      html.H5("Welcome to the Ingredible's Nutrition Assistant"),
      html.Br(),

        dbc.Accordion(
            [
                dbc.AccordionItem(
                    "This is the content of the first section",
                    title="Step 1",
                    item_id="acc_textarea",
                    html.Br(), html.Br(),
                    html.Label("Please paste your recipe here."),
                    dcc.Textarea(id='recipe-textarea',
                        value='',
                        style={'width': '80%', 'height':500},
                        placeholder='Please note: All information in brackets or parantheses will be deleted.'),
                    html.Br(), html.Br(),
                    html.Button('Submit Recipe', id='recipe-textarea-submit-button', n_clicks=0),
                    html.Br(), html.Br(),

                    HTML.DIV(ID="MSG"),
This is the line that seems to be causing the problem:   
                     ), 

                  dbc.AccordionItem(
                    "This is the content of the second section",
                    title="Item 2",
                    item_id="acc_datatable",
                ),
                dbc.AccordionItem(
                    "This is the content of the third section",
                    title="Item 3",
                    item_id="acc_report",
                ),
            ],
            id="accordion",
            active_item="acc_textarea",
        ),
        html.Div(id="accordion-contents", className="mt-3"),
    ]
)

@app.callback(
    Output("accordion-contents", "children"),
    [Input("accordion", "active_item")],
)
def change_item(item):
    return f"Item selected: {item}"

if __name__ == "__main__":
    app.run_server(debug=True, port=2000)

Hi @robertpfaff

To understand the error message, let’s take a look at one of your other Accordian items

dbc.AccordionItem(
    "This is the content of the second section",
    title="Item 2",
    item_id="acc_datatable",
),

This has three arguments, the first is a positional argument and the next two are keyword argument. (like regular Python functions) It’s a Dash convention that the first positional argument is the children property. So you could also write it this way:

dbc.AccordionItem(
    children = "This is the content of the second section",
    title="Item 2",
    item_id="acc_datatable",
),

Now if you want to add things to the AccorrdionItem Item you can make children a list:

dbc.AccordionItem(
    children = ["This is the content of the second section",  html.Div(id="MSG")],
    title="Item 2",
    item_id="acc_datatable",
),

But you also don’t need to include children= since it’s the first prop, so let’s turn it back into a positional argument:

dbc.AccordionItem(
     ["This is the content of the second section",  html.DIv(id="MSG")],
    title="Item 2",
    item_id="acc_datatable",
),

Like with any regular Python function, you got the error message because you tried to add other “children” elements as a positional argument after keyword arguments.

SyntaxError: positional argument follows keyword argument

For clarity, this will generate this error message: You have two positional arguments, and the second `html.Div(id=“MSG”) is after two keyword arguements.

dbc.AccordionItem(
    "This is the content of the second section", 
    title="Item 2",
    item_id="acc_datatable",
    html.DIv(id="MSG")
),

So, to put all the pieces together, here is the fix for the code you posted:
(Tip #1 try using a code formatter like black - it makes code easier to read and debug)

import dash
from dash import html, dcc, Input, Output, State
import dash_bootstrap_components as dbc


external_stylesheets = [dbc.themes.SUPERHERO]

app = dash.Dash(external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.Br(),
        html.H5("Welcome to the Ingredible's Nutrition Assistant"),
        html.Br(),
        dbc.Accordion(
            [
                dbc.AccordionItem(
                    [
                        "This is the content of the first section",
                        html.Br(),
                        html.Br(),
                        html.Label("Please paste your recipe here."),
                        dcc.Textarea(
                            id="recipe-textarea",
                            value="",
                            style={"width": "80%", "height": 500},
                            placeholder="Please note: All information in brackets or parantheses will be deleted.",
                        ),
                        html.Br(),
                        html.Br(),
                        html.Button(
                            "Submit Recipe",
                            id="recipe-textarea-submit-button",
                            n_clicks=0,
                        ),
                        html.Br(),
                        html.Br(),
                        html.Div(id="MSG"),
                    ],
                    title="Step 1",
                    item_id="acc_textarea",
                ),
                dbc.AccordionItem(
                    "This is the content of the second section",
                    title="Item 2",
                    item_id="acc_datatable",
                ),
                dbc.AccordionItem(
                    "This is the content of the third section",
                    title="Item 3",
                    item_id="acc_report",
                ),
            ],
            id="accordion",
            active_item="acc_textarea",
        ),
        html.Div(id="accordion-contents", className="mt-3"),
    ]
)


@app.callback(
    Output("accordion-contents", "children"),
    [Input("accordion", "active_item")],
)
def change_item(item):
    return f"Item selected: {item}"


if __name__ == "__main__":
    app.run_server(debug=True, port=2000)

Tip #2, you can use the Bootstrap classes in the classNames prop for spacing, so you don’t need to use `html.Br() for that. Here’s a cheatsheet with all the Bootstrap classes that you might find helpful:https://dashcheatsheet.pythonanywhere.com/

So the final is:

from dash import Dash, html, dcc, Input, Output, State
import dash_bootstrap_components as dbc


external_stylesheets = [dbc.themes.SUPERHERO]

app = Dash(external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.Br(),
        html.H5("Welcome to the Ingredible's Nutrition Assistant"),
        html.Br(),
        dbc.Accordion(
            [
                dbc.AccordionItem(
                    [
                        html.Div("This is the content of the first section", className="mb-4"),
                        html.Label("Please paste your recipe here."),
                        dcc.Textarea(
                            id="recipe-textarea",
                            value="",
                            style={"width": "80%", "height": 500},
                            placeholder="Please note: All information in brackets or parantheses will be deleted.",
                            className="mb-4"
                        ),
                        html.Button(
                            "Submit Recipe",
                            id="recipe-textarea-submit-button",
                            n_clicks=0,
                            className="mb-4"
                        ),
                        html.Div(id="MSG"),
                    ],
                    title="Step 1",
                    item_id="acc_textarea",
                ),
                dbc.AccordionItem(
                    "This is the content of the second section",
                    title="Item 2",
                    item_id="acc_datatable",
                ),
                dbc.AccordionItem(
                    "This is the content of the third section",
                    title="Item 3",
                    item_id="acc_report",
                ),
            ],
            id="accordion",
            active_item="acc_textarea",
        ),
        html.Div(id="accordion-contents", className="mt-3"),
    ]
)


@app.callback(
    Output("accordion-contents", "children"),
    [Input("accordion", "active_item")],
)
def change_item(item):
    return f"Item selected: {item}"


if __name__ == "__main__":
    app.run_server(debug=True, port=2000)

1 Like