4

Background

In my shiny module I run a lenghty calculation. I want to provide some visual feedback to the user by changing the cursor to the spinning circle. For this I created a css class .wait and was hoping to use shinyjs::addClass on the body to show the new cursor. However, within a module this does not work, while it does work in the main application. How can I get the desired behaviour into my module?

Code

library(shiny)
library(shinyjs)

testUI <- function(id) {
   ns <- NS(id)
   tagList(useShinyjs(),
           inlineCSS('.wait {cursor: wait;};'),
           actionButton(ns("wait"), "wait"),
           actionButton(ns("stop"), "stop"))
}

test <- function(input, output, session) {
   observeEvent(input$wait,  addClass(selector = "body", class = "wait"))
   observeEvent(input$stop,  removeClass(selector = "body", class = "wait"))
}

ui <- fluidPage(
   useShinyjs(),
   testUI("test"),
   div("Test to show that 'wait' class works", class = "wait"),
   actionButton("wait.main", "wait"),
   actionButton("stop.main", "stop")
) 
server <- function(input, output, session) {
    callModule(test, "test")
    observeEvent(input$wait.main,  addClass(selector = "body", class = "wait"))
    observeEvent(input$stop.main,  removeClass(selector = "body", class = "wait"))
}

shinyApp(ui = ui, server = server)
thothal
  • 16,690
  • 3
  • 36
  • 71

1 Answers1

5

This is a matter of scoping I guess. The easiest way to make this work is to use shinyjs::runjs to run the corresponding JavaScript code directly. In your module, use

observeEvent(input$wait,  runjs(code = '$("body").toggleClass("wait");'))
observeEvent(input$stop,  runjs(code = '$("body").toggleClass("wait");'))

This code does exactly the same as toggleClass(class = "wait", selector = "body").

This answer might help you with doing it the "shiny way":

observeEvent Shiny function used in a module does not work

Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98