daattali / shinyjs

💡 Easily improve the user experience of your Shiny apps in seconds
https://deanattali.com/shinyjs
Other
734 stars 119 forks source link

Explain to the user why button is disabled #239

Closed FedericoTrifoglio closed 3 years ago

FedericoTrifoglio commented 3 years ago

I'm trying to find a solution to tell the user why the button is disabled and what conditions need to be met to enable it. I want an alert, popover or tooltip to be produced only if the user either clicks or does a mouse hover over the disabled button.

I've tried {shinyBS} but couldn't manage to get it to work. So I've decided to take the JS route, although I'm a novice. I might need the message for the user to be produced by the Shiny server but I think I should easily pass it to JS with session$sendCustomMessage.

But before I even start thinking about that I need to understand, for example, why doesn't this work?

library(shiny)
library(shinyjs)

shinyApp(ui = fluidPage(
  tags$head(
    tags$script(HTML(
      "
      $(document).ready(function(){
        $('#mybutton').hover(function(){
        alert('I am disabled');
        });
      })
      "
    ))
  ),
  useShinyjs(),
  shinyjs::disabled(actionButton("mybutton", "Button"))
), server = server <- function(input, output, session) {}
)

When I hover over the button I can see the disabled icon as a tooltip (by the way I've tried to find how the tooltip is produced in the shinyjs' source code but couldn't find it), but the alert dialog is not shown. It's of course shown when the button is enabled.

daattali commented 3 years ago

This is a web thing, that caused headaches to a lot of people in history. Disabled elements do not trigger the hover event. It's by design, not something that shinyjs is doing.

If you add a title attribute to the button, that will get shown when you hover over the button, so you can use javascript to add/remove a title. I'm sure there are other solutions too, you can google for it but just don't look for shiny-specific solutions, google for how to do it in general in javascript.

FedericoTrifoglio commented 3 years ago

Thanks Dean for pointing me in the right direction. 'title' seems to be a good solution. Perhaps something along these lines.

UI

actionButton(inputId = "mybutton", label = "Button", title = "Initial tooltip") # title can perhaps be just "" when initialized

Server

mybutton_tooltip <- foo() # returns a string
observe({
      if (#some conditions here) {
          session$sendCustomMessage("updateMyButtonTooltip", mybutton_tooltip)
      }
})

JS

function updatedTooltip(mybutton_tooltip) {
  $('#mybutton').attr('title', mybutton_tooltip);
}
Shiny.addCustomMessageHandler('updateMyButtonTooltip', updatedTooltip);
daattali commented 3 years ago

Something along those lines yes. This isn't in the scope of shinyjs bugs/feature requests, so I can't help with this. If you're unable to find a solution, Twitter or RStudio Community or reddit or stackoverflow can be good places to get help.