In R Shiny, how to eliminate the flashing of observeEvent conditionals when first invoking the App?

In the below MWE code, the object input2 is optionally called by the user by clicking the "Show" radio button for Input 2. Default setting is to hide input2. However, when first invoking the App, input2 quickly flashes by before being hidden by the observeEvent.

This flashing is much more pronounced in the non-MWE version of the code.

There is a related post In R shiny, how to eliminate flashing of all conditional panels in sidebar when first invoking the App without using renderUI? that addresses this issue for conditionalPanel. But here there is no conditionalPanel.

I do not want to use renderUI to resolve this issue!! As renderUI has drawbacks I don't want to re-introduce.

MWE code:

library(shiny)
library(shinyjs)

f <- function(action,i){as.character(checkboxInput(paste0(action,i),label=NULL))}
actions       <- c("show", "reset")
tbl           <- t(outer(actions, c(1,2), FUN = Vectorize(f)))
colnames(tbl) <- c("Show", "Reset")
rownames(tbl) <- c("Input 2", "Input 3")

ui <- fluidPage(
  useShinyjs(),
  tags$head(
    tags$style(HTML(
      "td .checkbox {margin-top: 0; margin-bottom: 0;}
       td .form-group {margin-bottom: 0;}"
    ))
  ),
  br(),
  sidebarLayout(
    sidebarPanel(
      numericInput("input1", "Input 1:", 10, min = 1, max = 100),
      h5(strong("Add inputs:")),
      tableOutput("checkboxes"),
      numericInput("input2", "Input 2:", 10, min = 1, max = 100),
    ),
    mainPanel()
  )    
)

server <- function(input, output, session){
  
  output[["checkboxes"]] <- 
    renderTable({tbl}, 
                rownames = TRUE, align = "c",
                sanitize.text.function = function(x) x
    )

  observeEvent(input[["show1"]], {
    if(input[["show1"]] %% 2 == 1){shinyjs::show(id = "input2")} else
      {shinyjs::hide(id = "input2")}
  })

}

shinyApp(ui, server)

Upvotes: 0

Views: 266

Answers (2)

Pork Chop
Pork Chop

Reputation: 29417

You can also use hidden

hidden(numericInput("input2", "Input 2:", 10, min = 1, max = 100))

and toggle:

  observeEvent(input[["show1"]], {
    toggle("input2")
  },ignoreNULL = FALSE)

Upvotes: 1

danlooo
danlooo

Reputation: 10637

It takes some time in the event loop until observerEvent is called the first time. By default, it will be displayed at the very beginning. This results into a flash. Just hide input2 at the very beginning of the server function:

server <- function(input, output, session) {
  # Avoid flashing
  shinyjs::hide(id = "input2")
  
  output[["checkboxes"]] <-
    renderTable(
      {
        tbl
      },
      rownames = TRUE,
      align = "c",
      sanitize.text.function = function(x) x
    )

  observeEvent(input[["show1"]], {
    if (input[["show1"]] %% 2 == 1) {
      shinyjs::show(id = "input2")
    } else {
      shinyjs::hide(id = "input2")
    }
  })
}

Upvotes: 1

Related Questions