Hello guys,
I’m about to finish my scheduler alarm app, and I’m a bit stuck at the moment.
About the app:
It will be a simple value grab from the api with CRUD elements

This where I add a user and the email to the database( the user name value I use for checks in the app and the email for sending the email to the user)

Here is how the problem looks: I want here to get the name values from the api and when i selected the user to delete him via the button, but I’m stuck with it. I think the modal code and CRUD code does not align good.
The problem is that it gives me all the time Duplicate Outputs errors:
How do I code the def update_delete_user_dropdown: and def delete_user correctly?
Also if you know a better to make my modal_layout to looks like margins pls tell me ![]()
In the callback for output(s):
output-container-button.children
Output 0 (output-container-button.children) is already in use.
To resolve this, set allow_duplicate=True on
duplicate outputs, or combine the outputs into
one callback function, distinguishing the trigger
by using dash.callback_context if necessary.
The
def update_delete_user_dropdown: makes me problems when i comment it out I can get the modal layout.
Code:
the api function:
def get_emails():
response = requests.get('http://10.3.41.24:5001/api/emails')
if response.status_code == 200:
emails = response.json()
return emails
else:
print("Failed to fetch emails from the API")
return []
employee_positions = {}
emails = get_emails()
for email_data in emails:
name = email_data['name']
email = email_data['email']
employee_positions[name] = [email]
This is my modal
modal_layout = html.Div([
html.Div(id='modal-container', style={'display': 'none', 'position': 'fixed', 'width': '100%', 'height': '100%', 'top': '0', 'left': '0', 'background-color': 'rgba(0,0,0,0.5)', 'z-index': '1000'}),
html.Div(id='modal', style={'display': 'none', 'position': 'fixed', 'top': '50%', 'left': '80%', 'transform': 'translate(-50%, -50%)', 'z-index': '1001', 'background-color': 'white', 'margin': '20px'}, children=[
html.Div([
html.Button("X", id="close-modal", n_clicks=0, style={'position': 'absolute', 'top': '10px', 'right': '10px'}),
dcc.Tabs(id='modal-tabs', value='add-user', children=[
dcc.Tab(label='Add User', value='add-user', children=[
html.Div([
html.H3("Add New User"),
html.Label("Name:"),
dcc.Input(id='new-user-name', type='text', placeholder='Enter name...'),
html.Label("Email:"),
dcc.Input(id='new-user-email', type='email', placeholder='Enter email...'),
html.Button("Add User", id="add-user-button", n_clicks=0, className="btn btn-primary")
])
]),
dcc.Tab(label='Delete User', value='delete-user', children=[
html.Div([
html.H3("Delete User"),
html.Label("Select User:"),
dcc.Dropdown(id='delete-user-dropdown', options=[], placeholder='Select user...'),
html.Button("Delete User", id="delete-user-button", n_clicks=0, className="btn btn-danger")
])
])
])
], className='modal-content')
])
])
toggle modal:
@app.callback(
[Output('modal', 'style'),
Output('modal-container', 'style')],
[Input('add-new-user-button1', 'n_clicks'),
Input('close-modal', 'n_clicks')],
[State('modal', 'style')]
)
def toggle_modal(add_new_user_clicks, close_modal_clicks, modal_style):
ctx = dash.callback_context
if not ctx.triggered:
return modal_style, {'display': 'none'}
else:
button_id = ctx.triggered[0]['prop_id'].split('.')[0]
if button_id == 'add-new-user-button1':
modal_style['display'] = 'block'
return modal_style, {'display': 'block'}
elif button_id == 'close-modal' or button_id == 'add-user-button' or button_id == 'delete-user-button':
modal_style['display'] = 'none'
return modal_style, {'display': 'none'}
CRUD:
@app.callback(
Output('br206-employee-category-dropdown-alert1', 'options'),
[Input('add-user-button', 'n_clicks')],
[State('new-user-name', 'value'),
State('new-user-email', 'value')]
)
def add_new_user(n_clicks, name, email):
ctx = dash.callback_context
if not ctx.triggered or not name or not email:
return dash.no_update
else:
# Prepare data to be sent to the Flask API
data = {'name': name, 'email': email}
# Make a POST request to the Flask API endpoint
response = requests.post('http://10.3.41.24:5001/api/emails', json=data)
if response.status_code == 200:
print("User added successfully")
# Update the dropdown options with the new user
new_option = {'label': name, 'value': email}
employee_options = [{'label': key, 'value': key} for key in employee_positions.keys()]
employee_options.append(new_option)
return employee_options
else:
print("Failed to add user")
return dash.no_update
@app.callback(
Output('delete-user-dropdown', 'options'),
[Input('delete-user-button', 'n_clicks')],
[State('delete-user-dropdown', 'value')]
)
def update_delete_user_dropdown(n_clicks, selected_user):
ctx = dash.callback_context
if not ctx.triggered:
return dash.no_update
else:
#Fetch the list of emails from the API
if ctx.triggered[0]['prop_id'].split('.')[0] == 'delete-user-button':
response = requests.get('http://10.3.41.24:5001/api/emails')
if response.status_code == 200:
emails = response.json()
#Populate the dropdown with email options
options = [{'label': email['name'], 'value': email['email']} for email in emails]
return options
else:
print("Failed to fetch emails from the API")
return dash.no_update
else:
return dash.no_update
@app.callback(
[Output('delete-user-dropdown', 'options'),
Output('delete-user-dropdown', 'value')],
[Input('delete-user-button', 'n_clicks')],
[State('delete-user-dropdown', 'value')]
)
def delete_user(n_clicks, selected_user):
ctx = dash.callback_context
if not ctx.triggered:
return dash.no_update, None
else:
# Perform API call to delete the selected user from the database
if selected_user:
response = requests.delete(f'http://10.3.41.24:5001/api/emails/{selected_user}')
if response.status_code == 200:
print("User deleted successfully")
else:
print("Failed to delete user")
# Retrieve updated user list from the API
response = requests.get('http://10.3.41.24:5001/api/emails')
if response.status_code == 200:
user_data = response.json()
# Update the dropdown options after deletion
employee_options = [{'label': user['name'], 'value': user['email']} for user in user_data]
return employee_options, None
else:
return dash.no_update, None