Search code examples
rshinyreactive

Flickering of dataTableOutput when manipulating with sliderValues


In a shiny app I add reactive values to a datatable with sliderInput:

library(shiny)
library(shinyWidgets)
library(DT)

ui <- fluidPage(
  sliderInput("a", "A", min = 0, max = 3, value = 0, width = "250px"),
  titlePanel("Sliders"),
  dataTableOutput("sliderValues", width="450px")
)
server <- function(input, output, session) {
  
  sliderValues <- reactive({
    df <- data.frame(
      Name = "A", 
      Value = as.character(c(input$a)), 
      stringsAsFactors = FALSE) %>% 
      pivot_wider(names_from = Name, values_from = Value)
    
    return(df)
  })

  
  # Show the values in an HTML table in a wider format----
  output$sliderValues <- DT::renderDataTable({
    DT::datatable(sliderValues(),
                  extensions = c('Buttons'),
                  options = list(
                    dom = 'frtBip',
                    buttons = list(list(extend = 'excel', filename = paste0("myname-", Sys.Date())))
                  )
    )
  })

}
shinyApp(ui, server)

By doing so I realized that the table flickers each time I move the slider. What is the reason for this and how can we solve it?

Here is a example of what I am talking about. Note the 3 dots flickering at the middle to end of the gif: enter image description here


Solution

  • You can use dataTableProxy, this way only the data will be pushed to the client, instead of recreating the object everytime with the vanilla approach you have. I've also added the processing=FALSE to the options so its not creating other messages such as Processing...

    library(shiny)
    library(shinyWidgets)
    library(DT)
    library(tidyr)
    
    ui <- fluidPage(
      sliderInput("a", "A", min = 0, max = 3, value = 0, width = "250px"),
      titlePanel("Sliders"),
      DT::DTOutput(outputId = "sliderValues", width="450px")
    )
    server <- function(input, output, session) {
      
      sliderValues <- reactive({
        df <- data.frame(
          Name = "A", 
          Value = as.character(c(input$a)), 
          stringsAsFactors = FALSE) %>% 
          pivot_wider(names_from = Name, values_from = Value)
        return(df)
      })
      
      
      # Show the values in an HTML table in a wider format----
      output$sliderValues <- DT::renderDT({
        DT::datatable(isolate(sliderValues()),
                      extensions = c('Buttons'),
                      options = list(processing=FALSE,
                        dom = 'frtBip',
                        buttons = list(list(extend = 'excel', filename = paste0("myname-", Sys.Date())))
                      )
        )
      })
      
      
      proxy <- dataTableProxy('sliderValues')
      
      observe({
        replaceData(proxy, sliderValues())
      })
      
    }
    shinyApp(ui, server)