How to change slider bar color using setSliderColor on multiple sliders when using renderUI in R Shiny

518 views Asked by At

I have multiple sliders that are reactive upon other data that I want to change the color of. I'm trying to avoid long bouts of CSS code, so I'd like to use shinyWidget's setSliderColor() function is possible. This answer worked when I just had one slider, but now that I have two sliders, it won't work. Here's a reproducible example:

library(shiny)
library(shinyWidgets)


ui <- fluidPage(
    
    
    sidebarLayout(
        sidebarPanel(
            textInput(inputId = "greeting",
                      label = "Say hi!"),
            actionButton(inputId = "submit", 
                         label = "Submit"),
            
            uiOutput("num_slider"),
            uiOutput("num_slider2"),
            
            
        ),
        mainPanel(DT::DTOutput("table"))
    ))

server <- function(input, output) {
    
        data <- reactive({
            req(input$submit)
            if(input$greeting == "hi!") {
            tibble(name = c("Justin", "Corey", "Sibley"),
                       grade = c(50, 100, 100))}
        })
        
        output$table <- renderDT({
            datatable(data())
        })
        
        
        output$num_slider <- renderUI({
            
            if(length(data()) > 0) {
                
                fluidPage(setSliderColor("#CA001B", sliderId = 1),
                          sliderInput(inputId = "num_filter2",
                                      label = "Filter by Number",
                                      min = 1,
                                      max = 10,
                                      value = c(1, 10)))}
            
        })
        
        output$num_slider2 <- renderUI({
            
            if(length(data()) > 0) {
                #This one won't change color
                fluidPage(setSliderColor("#CA001B", sliderId = 2),
                          sliderInput(inputId = "num_filter2",
                                      label = "Filter by Number",
                                      min = 100,
                                      max = 10000,
                                      value = c(100, 10000)))}
            
        })
    
}

# Run the application 
shinyApp(ui = ui, server = server)

I've tried changing the sliderId to both be 1, or to even go from -100:100, but I can only get it to change one slider. Strangely, in my real dashboard, it only changes the last one but doesn't change earlier sliders, but in this one, it only changes the first one. I wonder if it could do with the order that I coded it? Any help would be appreciated!

2

There are 2 answers

1
schlumpel On BEST ANSWER

i got your code running by combining two color-switches into one setSliderColor(). Like this, its not that comfortable to change on different conditions, though.

library(shiny)
library(shinyWidgets)
library(DT) # added DT lib

ui <- fluidPage(
  
  
  sidebarLayout(
    sidebarPanel(
      textInput(inputId = "greeting",
                label = "Say hi!",value = "hi!"), #to not always click
      actionButton(inputId = "submit", 
                   label = "Submit"),
      
      uiOutput("num_slider1"),
      uiOutput("num_slider2"),
      
      
    ),
    mainPanel(DT::DTOutput("table"))
  ))

server <- function(input, output) {
  
  data <- reactive({
    req(input$submit |  0==0) #to not always click
    if(input$greeting == "hi!") {
      tibble(name = c("Justin", "Corey", "Sibley"),
             grade = c(50, 100, 100))}
  })
  
  output$table <- renderDT({
    datatable(data())
  })
  
  
  output$num_slider1 <- renderUI({
    
    if(length(data()) > 0) {
      
      fluidPage(setSliderColor(c("#CA001B","green"), sliderId = c(1,2)), #put vectors here to change the colors
                sliderInput(inputId = "num_slider1",
                            label = "Filter by Number",
                            min = 1,
                            max = 10,
                            value = c(1, 10)))}
    
  })
  
  output$num_slider2 <- renderUI({
    
    if(length(data()) > 0) {
      #This one won't change color
      #fluidPage(setSliderColor("yellow", sliderId = 2),
                sliderInput(inputId = "num_slider2",
                            label = "Filter by Number",
                            min = 100,
                            max = 10000,
                            value = c(100, 10000)))}
    
  })
  
}

# Run the application 
shinyApp(ui = ui, server = server)
0
jpdugo17 On

I adjusted the code so it can have different persistent colors among the outputs. Notice how the sliderInput that is not part of renderUI also changes color. I also removed the FluidPage call inside renderUI because it was affecting the size of the inputs and wasn't really necessary (as setSliderColor returns a tags$head() object).

library(shiny)
library(shinyWidgets)


ui <- fluidPage(
    setSliderColor('orange', sliderId = c(1)),
    
    sidebarLayout(
        
        sidebarPanel(
            textInput(inputId = "greeting",
                      label = "Say hi!"),
            actionButton(inputId = "submit", 
                         label = "Submit"),
            
            uiOutput("num_slider"),
            sliderInput(inputId = "num_filter1",
                        label = "Now it works!",
                        min = 1,
                        max = 10,
                        value = c(1, 10))
            
        ),
        mainPanel()
    ))

server <- function(input, output) {
    
    i <- reactiveValues()
    i$color <- 1
    i$color_name <- 'violet'
    
    
    observeEvent(input$submit, {
        
        i$color <- c(i$color, i$color[[length(i$color)]] + 1, i$color[[length(i$color)]] + 2)
        i$color_name <- c(i$color_name, 'green', 'red')
        
        #left for demonstration purposes
        print(i$color)
        print(i$color_name)
        
        shiny::req(input$greeting)
        shiny::req(input$submit)
        
        
        output$num_slider <- renderUI({
            
            if(input$greeting == "hi!") {
                
                tagList(setSliderColor(i$color_name, sliderId = i$color),
                          sliderInput(inputId = "num_filter1",
                                      label = "Filter by Number",
                                      min = 1,
                                      max = 10,
                                      value = c(1, 10)),
            
               
                      sliderInput(inputId = "num_filter2",
                                  label = "Filter by Number",
                                  min = 1,
                                  max = 10,
                                  value = c(1, 10)))}
            
            
        }) }) 
    
}

# Run the application 
shinyApp(ui = ui, server = server)