JeanBertin
JeanBertin

Reputation: 703

Highlight R shiny selectInput item without clicking on it

Is it possible to make a reactive shiny output that directly shows what is pointed by user's mouse ?

To illustrate, in the following reproductible example, I would like this Shiny app to print what is beneath the mouse cursor without having to click on it.

library(shiny)

ui <-fluidPage(
   titlePanel("Transports"),

sidebarLayout(
   sidebarPanel(
      selectInput("var", 
              label = "Variable to display when user moves the mouse over it",  
              choices = c("car", "boat","plane"),selected = "car")

      ),

mainPanel(
  textOutput("selected_var")
         )
    )
)

server <- function(input, output) {

   output$selected_var <- renderText({ 
      paste("You have selected the", input$var)
   })

}
shinyApp(ui = ui,server = server)

Thanks in advance

Upvotes: 2

Views: 1010

Answers (2)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

Another way, using some Javascript in the onInitialize option. An option is selected if the mouse cursor stays one second on this option. You can choose another value of the delay. I find the delay is useful. It allows to move the cursor through the dropdown menu, without selecting an option whenever the cursor touches it.

enter image description here

library(shiny)

jscode <- "function(){
var delay = 1000; // 1000ms = 1s
var setTimeoutConst;
$('.selectize-control')
  .on('mouseenter', '.selectize-dropdown-content div .option', function(){
    var $this = $(this);
    clearTimeout(setTimeoutConst);
    setTimeoutConst = setTimeout(function(){
      $this.click();
    }, delay);
  } 
).on('mouseleave', function(){
  clearTimeout(setTimeoutConst);
  });
}"
shinyApp(
  ui = fluidPage(
    selectizeInput("state", "Choose a state:",
                   list(`East Coast` = c("NY", "NJ", "CT"),
                        `West Coast` = c("WA", "OR", "CA"),
                        `Midwest` = c("MN", "WI", "IA")),
                   options = list(onInitialize = I(jscode))
    ),
    textOutput("result")
  ),
  server = function(input, output) {
    output$result <- renderText({
      paste("You chose", input$state)
    })
  }
)
}

Upvotes: 3

thothal
thothal

Reputation: 20329

You can add an event listener to your element in which you send a message to shiny which you can then show:

library(shiny)
library(shinyjs)

ui <-fluidPage(
   useShinyjs(debug = TRUE),
   titlePanel("Transports"),

sidebarLayout(
   sidebarPanel(
      selectInput("var", 
              label = "Variable to display when user moves the mouse over it",  
              choices = c("car", "boat","plane"),selected = "car")

      ),

mainPanel(
  textOutput("selected_var")
         )
    )
)

server <- function(input, output) {
   runjs("$('.selectize-control').on('mouseenter', '.selectize-dropdown-content div', function() {Shiny.setInputValue('selected', $(this).data('value'));})")
   output$selected_var <- renderText({ 
      paste("You have selected the", input$selected)
   })

}
shinyApp(ui = ui,server = server)

Upvotes: 2

Related Questions