I want to create dropdown menus that update based on the previous selection using python widgets where the next dropdown doesn't appear until the previous is selected and the number of dropdowns are not hardcoded into the code.
For example:
Example 1: First dropdown selection: Category A Category B Next dropdown selections based on Category A selection: Category A1 Category A2 Next Dropdown Selection if A1 was selected: Category A1.1 Category A1.2
Example 2: First dropdown selection: Category A Category B Next dropdown selections based on Category B selection: Category B1 Category B2 Next Dropdown Selection if B2 was selected: Category B2.1 Category B2.2 Next Dropdown selection if B2.1 was selected: B2.1.1
Example 3: First dropdown selection: Category A Category B Next dropdown selections based on Category B selection: Category B1 Category B2 Next Dropdown Selection if B2 was selected: Category B2.1 Category B2.2 Next Dropdown selection if B2.2 was selected: B2.2.1 Next Dropdown selection if B2.2.1 was selected: B2.2.1.1
I tried the following, but it is not populating correctly.
import ipywidgets as widgets
data = {'product_id': ['p1', 'p2', 'p3', 'p4', 'p5', 'p6'],
'categories': ['Category A/Category A1/Category A1.1',
'Category A/Category A1/Category A1.2',
'Category A/Category A2/Category A2.1',
'Category B/Category B1/Category B1.1/Category B1.1.1',
'Category B/Category B2/Category B2.1/Category B2.1.1',
'Category B/Category B2/Category B2.2/Category B2.2.1/Category B2.2.1.1']}
# Extract all categories from data
categories = set()
for category_path in data['categories']:
categories.update(category_path.split('/'))
# Create a dictionary that maps each category to its parent
parent_dict = {}
for category in categories:
parent_dict[category] = '/'.join(category.split('/')[:-1])
# Create dropdown menus
dropdowns = []
prev_dropdown = None
for category in sorted(categories):
options = [''] + [c for c in categories if parent_dict[c] == category]
dropdown = widgets.Dropdown(options=options)
if prev_dropdown is not None:
def observe_dropdown(change, prev_dropdown=prev_dropdown, dropdown=dropdown):
prev_value = prev_dropdown.value
if prev_value != '':
dropdown.options = [''] + [c.split('/')[-1] for c in data['categories'] if c.startswith(prev_value+'/'+change.new+'/')]
else:
dropdown.options = ['']
dropdown.value = ''
prev_dropdown.observe(observe_dropdown, 'value')
prev_dropdown = dropdown
dropdowns.append(dropdown)
# Display dropdown menus
widgets.VBox(dropdowns)