Is there a way to deselect a dash component (i.e. remove focus)?

Hey all

I’m having some trouble with tooltips and dash bootstrap buttons in my app.

The problem:
If I add a tooltip to my dcc button that triggers a modal, when the modal closes, the tooltip annoyingly persists on the button despite the mouse being somewhere else on the screen.

It’s like the tooltip jams on as if the button had been selected by manually scrolling through the components using the tab key, but it was NOT selected by the keyboard, and so I don’t want to the tooltip to remain ‘on’. The only way to hide the tooltip after the modal is closed it is to hover the mouse over and off the button, or manually tab to another component.

This has cost me 2 hours of pain already and I still can’t solve it. I think it’s something to do with the automatic ‘focus’ or ‘outline’. I’ve tried manually switching button active state on/off but it’s not that. It’s the focus ring around the button that causes the pop up to persist after the modal closes. Im sure there must be an easier way then writing custom CSS to get around this.

Is there a way in dash to manually de-focus the browser from a button component?? (different to active state)

or

Is there a way to manually select a page component (i.e. reset the selection to the initial page load state where no buttons have been selected)?

image

Just in case anyone is interested, I’ve finally solved this issue.

Aware that in general you don’t want to remove ‘focus’ from a component manually as this is not good for accessibility purposes (keyboard users, vision impaired ppl etc). But in this case, the button focus in dash keeps getting triggered when I leave a modal, which then triggers the tooltip unnecessarily.

The quickest and dirtiest solution I’ve found is to embed a little clientside javascript callback in my dash app that is triggered by the button in question. You can then manually unfocus it with .blur() or refocus on another component with .focus().

Code below that just needs to be somewhere in your main python code for the dash app. Be careful if you are copying it because the inverted commas get a bit screwy from this markup.

#Test client side callback
app.clientside_callback(
“”"
function() {
alert(“Client side callback triggered”);
//document.getElementById(“some-other-component”).focus(); //use this to set the focus on whatever component you want
document.getElementById(“some-component”).blur(); //this will remove the focus from a selected component
return;
}
“”",
Output(‘blur-hidden-div’, ‘value’), #Callback needs an output, so this is dummy
Input(‘some-component’, ‘n_clicks’), #This triggers the javascript callback
prevent_initial_call=True
)

In this case I trigger the clienside callback with an input (some-component), which then runs the embedded javascript where I manually blur the focus of that component. You have to have an output for the callback. so I output to a hidden div component.

I had a problem with an dcc.Input that kept the focus after the user had entered return. The trick
I used to remove the focus was in the callback that handles the input n_submit I re-render the input component.

In the callback you must also assign a new key attribute to the input’s parent container otherwise the update will be ignored.