☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Confirmation dialog on button press

Community Support
spano
spano

I’m currently using bokeh serve and wanted to have a confirmation dialog when a button is pressed before executing some python code. There are some old posts from 2016 about dialogs, but that seems to be deprecated. I’ve come up with the code below. Basically I use two hidden PreText widgets to trigger javascript and python calls when their text is changed. It seems to work, but I feel like there is a better way. Thoughts?

import uuid                                                                     
                                                                                
from bokeh.io import curdoc                                                     
from bokeh.layouts import column                                                
from bokeh.models import Button, CustomJS, PreText                              
                                                                                
# Global to store everything                                                    
STATE = {}

# What function to call if confirmation is yes                                  
STATE['confirm_func'] = None                                                    
                                                                                
# triggers confirmation by changing the value in confirm_text                   
def trigger_confirm(text):                                                      
    # add in uuid so it's allways different                                     
    STATE['confirm_text'].text = str(uuid.uuid4()) + text                       
                                                                                
# handles confirmation when value in confirm_res is changed                     
def handle_confirm(attr, old, new):                                             
    if STATE['confirm_func'] is None:                                           
        return                                                                  
    if STATE['confirm_res'].text.strip() == 'yes':                              
        STATE['confirm_func']()                                                 
    STATE['confirm_func'] = None                                                
                                                                                
# Call right after button is pressed                                            
def button_callback(event):                                                     
    # Set function to call on yes result                                        
    STATE['confirm_func'] = button_action                                       
                                                                                
    trigger_confirm("Are you sure you want to push the button?") 
    # This occurs right away, doesn't wait for dialog to be done               
                                                                                
# Actual action to perform after confirmation dialog                            
def button_action():                                                            
    print("=====Button action done=====")                                       
                                                                                
STATE['confirm_text'] = PreText(text="")                                        
STATE['confirm_res'] = PreText(text="")                                         
                                                                                
confirm_js = CustomJS(                                                          
    args=dict(confirm_text=STATE['confirm_text'], confirm_res=STATE['confirm_res']),
    code=                                                                       
    '''                                                                         
        // Remove uuid from text                                                
        let confirm_str = confirm_text.text.substring(36);                      
                                                                                
        // Create dialog                                                        
        let dialog_ans = confirm(confirm_str);                                  
        let res = '';                                                           
        if (dialog_ans) {                                                       
            console.log("yes");                                                 
                                                                                
            // handle where no change in result still triggers callback         
            if (confirm_res.text == 'yes') {                                    
                res = 'yes ';                                                   
            } else {                                                            
                res = 'yes';                                                    
            }                                                                   
        } else {                                                                
            console.log("no");                                                  
                                                                                
            // handle where no change in result still triggers callback         
            if (confirm_res.text == 'yes') {                                    
                res = 'no ';                                                    
            } else {                                                            
                res = 'no';                                                     
            }                                                                   
        }                                                                       
        console.log(res);                                                       
        confirm_res.text = res;                                                 
    '''                                                                         
)                                                                               
                                                                                
# Set up callbacks                                                              
STATE['confirm_text'].js_on_change('text', confirm_js)                          
STATE['confirm_res'].on_change('text', handle_confirm)                          
                                                                                
# Generic button                                                                
STATE['button'] = Button(label='Do something')                                  
STATE['button'].on_click(button_callback)                                       
                                                                                
# Hide the dummy text widgets                                                   
STATE['confirm_res'].visible = False                                            
STATE['confirm_text'].visible = False                                           
                                                                                
                                                                                
# Add everything to doc so it syncs                                             
curdoc().add_root(column(STATE['confirm_text'], STATE['confirm_res'], STATE['button']))

⌁   Link to post
spano
spano

Much appreciated. I did not know that. Unfortunately, for other reasons, I’m stuck on Python 3.6 at the moment so I cannot upgrade. I’ll just live with my hack until I can get off 3.6 and upgrade Bokeh versions.

⌁   Link to post

End of archived discussion · Replies are disabled