Dropdown doesn't want to update

My dropdown won’t update, I’ve tried to create a log to make sure my callback function is called, and it works. But the sub dropdown won’t update.
this is my layout file

import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
import pandas as pd
from dash import dcc, html

import constants, common


def get_category(df):
    categories = df['sub_name'].unique().tolist()
    selected_category = categories[0]
    sub_categories = df[df['sub_name'] == selected_category]['title'].unique().tolist()

    category_menu1 = dmc.Select(
        data=[{'label': category, 'value': category} for category in categories],
        value=selected_category,
        label='Category',
        id='category_menu1',
        searchable=True,
        style=dict(width='100%')
    )

    sub_categories_menu1 = dmc.Select(
        data=[{'label': sub_category, 'value': sub_category} for sub_category in sub_categories],
        value=sub_categories[0],
        label='Sub-Category',
        id='sub_categories_menu1',
        searchable=True,
        style=dict(width='100%')
    )

    category_card = dmc.Card(
        children=[category_menu1],
        withBorder=True,
        shadow="sm",
        radius="md",
    )
    sub_category_card = dmc.Card(
        children=[sub_categories_menu1],
        withBorder=True,
        shadow="sm",
        radius="md",
    )

    category_col = dmc.Col(
        [category_card],
        xs=12, sm=12, md=6, lg=6, xl=6,
        style=dict()
    )

    sub_category_col = dmc.Col(
        [sub_category_card],
        xs=12, sm=12, md=6, lg=6, xl=6,
        style=dict()
    )

    layout = dmc.Grid(
        [category_col, sub_category_col]
    )

    return layout


def province_analysis_layout():
    df=constants.DATA_PROVINCE

    cat_col = get_category(df.copy())

    layout = dmc.Grid([cat_col], justify='center')

    return layout

and this is my callbacks file

import dash
import pandas as pd
from dash.dcc import send_data_frame
from dash.dependencies import Input, Output, State

import constants, common

import constants


def add_province_callbacks(app: dash.Dash):

    

    @app.callback(
        Output('sub_categories_menu1', 'options'),
        [Input('category_menu1', 'value')],
        prevent_initial_call=True
    )
    def update_sub_categories(selected_category, previous_selected_category):
        print(f"Selected category: {selected_category}")
        df=constants.DATA_PROVINCE
        filtered_rows = df[df['sub_name'] == selected_category]
        sub_categories = filtered_rows['title'].unique().tolist()
        print(f"Sub-categories for '{selected_category}': {sub_categories}")  # Added logging
        return [{'label': sub_category, 'value': sub_category} for sub_category in sub_categories]

Hi @nurqoneah and welcome to the Dash commnity :slight_smile:

There is not quite enough information here to help. Could you make a complete minimal example that replicates the issue?

Hi @AnnMarieW , thank you for welcoming me so warmly.

so this is how I have a dataset with 266 rows, each row has a different title, and has one of the sub_name (there are 33 sub_name). for example

title sub_name
a 1
b 1
c 2
d 2
e 2

when I have selected the sub_name(category) then what comes out in my second dropdown(sub_category) are only the ones that have the sub_name that I selected.

this is an example of the print() result in my callbacks function
Selected category: Industri
Sub-categories for ‘Industri’: [‘IBS’, ‘IMK’, ‘Jumlah Perusahaan pada Industri Besar dan Sedang’, ‘Jumlah Tenaga Kerja Pada Industri Besar dan sedang’, ‘Nilai Produksi pada Industri Besar dan Sedang’, 'Jumlah Perusahaan pada Industri Mikro dan Kecil ', ‘Jumlah Tenaga Kerja pada Industri Mikro dan Kecil’, ‘Nilai Produksi pada Industri Mikro dan Kecil’]

Hi @nurqoneah

I understand what you are trying to do. It will be easier to help if you can provide an example that I can copy and run locally and see the same error you do. More info on how to do that here:

Hi, @AnnMarieW

Dash version 2.9.3, dmc version 0.12.1, html version 2.0.11, stadata version 1.0.0, dash-bootstrap-components version 1.4.1, dash-mantine-component version 0.12.1, Flask version2.3.2

This is my code that you can run

from flask import Flask
import dash
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc
from dash import html
from dash.dependencies import Input, Output
import stadata

client = stadata.Client('0b5b67b65383eb275017dd5a676a0a38')

DATA_PROVINCE = client.list_dynamictable(all=False, domain=['1400'])

server = Flask(__name__)

app = dash.Dash(
    __name__,
    suppress_callback_exceptions=True,
    assets_folder='assets',
    server=server,
    title='Badan Pusat Statistik Provinsi Riau',
    external_stylesheets=[dbc.themes.BOOTSTRAP]
)

def get_category(df):
    categories = df['sub_name'].unique().tolist()
    selected_category = categories[0]
    sub_categories = df[df['sub_name'] == selected_category]['title'].unique().tolist()

    category_menu1 = dmc.Select(
        data=[{'label': category, 'value': category} for category in categories],
        value=selected_category,
        label='Category',
        id='category_menu1',
        searchable=True,
        className="custom-dropdown"
    )

    sub_categories_menu1 = dmc.Select(
        data=[{'label': sub_category, 'value': sub_category} for sub_category in sub_categories],
        value=sub_categories[0],
        label='Sub-Category',
        id='sub_categories_menu1',
        searchable=True,
        className="custom-dropdown"
    )

    category_card = dmc.Card(
        children=[dmc.Col(html.Div(category_menu1), span=6)],
        withBorder=True,
        shadow="sm",
        radius="md",
    )

    sub_category_card = dmc.Card(
        children=[dmc.Col(html.Div(sub_categories_menu1), span=6)],
        withBorder=True,
        shadow="sm",
        radius="md",
    )

    category_col = dmc.Col(
        [category_card],
        xs=12, sm=12, md=6, lg=6, xl=6,
        style=dict()
    )

    sub_category_col = dmc.Col(
        [sub_category_card],
        xs=12, sm=12, md=6, lg=6, xl=6,
        style=dict()
    )

    layout = dmc.Grid(
        children=[category_col, sub_category_col],
        gutter=12,
        style=dict(paddingLeft='1.3rem', paddingRight='1.3rem')
    )

    return layout


def add_province_callbacks(app):
    @app.callback(
        Output('sub_categories_menu1', 'options'),
        [Input('category_menu1', 'value')]
    )
    def update_sub_categories(selected_category):
        df = DATA_PROVINCE
        print(dash.__version__), print(dmc.__version__), print(html.__version__)
        filtered_rows = df[df['sub_name'] == selected_category]
        sub_categories = filtered_rows['title'].unique().tolist()
        return [{'label': sub_category, 'value': sub_category} for sub_category in sub_categories]

def init_app(app):
    layout = get_category(DATA_PROVINCE)
    app.layout = layout
    add_province_callbacks(app)

if __name__ == "__main__":
    init_app(app)
    app.run_server(debug=False, port=8570)

Hi @nurqoneah

That was helpful - thanks :slight_smile:

A couple issues:

Try changing your callback to:



def add_province_callbacks(app):
    @app.callback(
        Output('sub_categories_menu1', 'data'),
        Output('sub_categories_menu1', 'value'),
        [Input('category_menu1', 'value')]
    )
    def update_sub_categories(selected_category):
        df = DATA_PROVINCE
        filtered_rows = df[df['sub_name'] == selected_category]
        sub_categories = filtered_rows['title'].unique().tolist()
        return [{'label': sub_category, 'value': sub_category} for sub_category in sub_categories], sub_categories[0]
  • The prop is called data not options —> Output('sub_categories_menu1', 'data'),
  • Since the Select component is searchable, having the value from the previous Category made is so the options didn’t show anything. You could also set the value prop as shown in the callback above. Alternately, you could just set searchable=False in the dmc.Select

Next, take the Sub Category Menu out of the card. It seems like the card is preventing the dropdown options from displaying. Not sure what the solution is - I tried setting the zIndex prop of the dmc.Select, but it didn’t seem to work. It’s probably some CSS issue.

Try changing the sub_category_card to:

 sub_category_card = dmc.Col(html.Div(sub_categories_menu1), span=6)

2 Likes

Thank you @AnnMarieW , it’s solved. :star_struck:

1 Like