简体   繁体   中英

Applying 2 different CSS styles on Shiny Button

I am developing a R Shiny Application that use the shinyWidgets library. I use 2 times the radioGroupButtons widget. I would like to make it green the first time, and red the second time, using CSS . (In reality I want to make more customisation).

Here is a basic code, applying CSS to every buttons. How can I apply 2 CSS classes?

Thank you very very much for your help !

library("shinyWidgets")
library(shiny)

# Useless server
server <- function(input, output) {
  output$distPlot <- renderPlot({
    hist(rnorm(input$button1), col = 'skyblue', border = 'white')
  })
}

# Ui
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(

        # A CSS for every .btn button
        tags$style(HTML("
            .btn {
              color: #2ecc71;
              border: 2px #2ecc71 solid;
            }
            .btn:hover {
                color: #fff;
                background-color: #2ecc71;
            }
            .btn-default.active, .btn-default:active, .open > .dropdown-toggle.btn-default {
                color: #fff;
                background-color: #2ecc71;
                border-color: #2ecc71;
            }
        ")),

        # first radio button, it is green!
        radioGroupButtons("button1", label = "It's green !!", choices=c("choice1"=50, "Choice2"=100, "Choice3"=150), selected=100),

        # second radio button, I wish it is red!
        radioGroupButtons("button2", label = "I wish I was red :( ...", choices=c("choice1"=1, "Choice2"=2), selected=1)
    ),
    mainPanel(plotOutput("distPlot"))
  )
)

shinyApp(ui = ui, server = server)

So you want to add some specific classes to your radioGroupButtons . Well, ShinyWidgets doesn't let you, so why not create your own radioButtons widget function.

(Well, this function will be almost entirely copied from radioGroupButtons )

Hint: Type radioGroupButton into the R Console to view the source code.

And lets tweak that function, such that it accepts a class argument, which will be applied to the html element. Then, you can easily access the different radioGroupButton -classes with your CSS.

Working code below:

library("shinyWidgets")
library(shiny)

# Defining the new Widget. 
customRadioGroupButtons <- function (inputId, label = NULL, choices, selected = NULL, status = "default", size = "normal", direction = "horizontal", justified = FALSE, individual = FALSE, checkIcon = list(), class=NULL) {
  choices <- shinyWidgets:::choicesWithNames(choices)
  if (!is.null(selected) && length(selected) > 1) 
    stop("selected must be length 1")
  if (is.null(selected)) 
    selected <- choices[1]
  size <- match.arg(arg = size, choices = c("xs", "sm", "normal", 
                                            "lg"))
  direction <- match.arg(arg = direction, choices = c("horizontal", 
                                                      "vertical"))
  status <- match.arg(arg = status, choices = c("default", 
                                                "primary", "success", "info", "warning", "danger"))
  divClass <- if (individual) 
    ""
  else "btn-group"
  if (!individual & direction == "vertical") {
    divClass <- paste0(divClass, "-vertical")
  }
  if (justified) {
    divClass <- paste(divClass, "btn-group-justified")
  }
  if (size != "normal") {
    divClass <- paste0(divClass, " btn-group-", size)
  }

  # Below here, the paste call is the only difference to the original function.
  radioGroupButtonsTag <- tagList(tags$div(id = inputId, class = paste("radioGroupButtons", class), 
    if (!is.null(label)) 
      tags$label(class = "control-label", `for` = inputId, label),
    if (!is.null(label)) 
      br(), style = "margin-top: 3px; margin-bottom: 3px; ", style = if (justified) "width: 100%;", 
      tags$div(class = divClass, role = "group", 
      `aria-label` = "...", `data-toggle` = "buttons", 
      class = "btn-group-container-sw", shinyWidgets:::generateRGB(inputId, choices, selected, status, size, checkIcon))))
  shinyWidgets:::attachShinyWidgetsDep(radioGroupButtonsTag)
}

# Useless server
server <- function(input, output) {
  output$distPlot <- renderPlot({
    hist(rnorm(input$button1), col = 'skyblue', border = 'white')
  })
}

# Ui
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(

      # Note: Consider making a function if you use this more often.
      tags$style(HTML("
                      .radioGroupButtons.green .btn {
                        color: #2ecc71;
                        border: 2px #2ecc71 solid;
                      }
                      .radioGroupButtons.green .btn:hover {
                        color: #fff;
                        background-color: #2ecc71;
                      }
                      .radioGroupButtons.green .btn-default.active, .radioGroupButtons.green .btn-default:active, .radioGroupButtons.green .open > .dropdown-toggle.btn-default {
                        color: #fff;
                        background-color: #2ecc71;
                        border-color: #2ecc71;
                      }

                      .radioGroupButtons.red .btn {
                        color: #EE102B;
                        border: 2px #EE102B solid;
                      }
                      .radioGroupButtons.red .btn:hover {
                        color: #fff;
                        background-color: #EE102B;
                      }
                      .radioGroupButtons.red .btn-default.active, .radioGroupButtons.green .btn-default:active, .radioGroupButtons.green .open > .dropdown-toggle.btn-default {
                        color: #fff;
                        background-color: #EE102B;
                        border-color: #EE102B;
                      }
                      ")),

      # first radio button, it is green!
      customRadioGroupButtons("button1", class="green", label = "It's green !!", choices=c("choice1"=50, "Choice2"=100, "Choice3"=150), selected=100),

      # second radio button, I wish it is red!
      customRadioGroupButtons("button2", class="red", label = "I wish I was red :( ...", choices=c("choice1"=1, "Choice2"=2), selected=1)
      ),
    mainPanel(plotOutput("distPlot"))
      )
    )

shinyApp(ui = ui, server = server)

You can add a Bootstrap status then overwrite the class, for example if you add status = "danger" , buttons will have class btn-danger :

I can remove the limitation to valid Bootstrap status in the function, it could be useful for such styling (fill an issue here so i remenber).

library("shinyWidgets")
library("shiny")

# Useless server
server <- function(input, output) {
  output$distPlot <- renderPlot({
    hist(rnorm(input$button1), col = 'skyblue', border = 'white')
  })
}

# Ui
ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(

      # A CSS for every .btn button
      tags$style(HTML("
                      .btn-success.btn {
                      color: #2ecc71;
                      background-color: #fff;
                      border: 2px #2ecc71 solid;
                      }
                      .btn-success.btn:hover {
                      color: #fff;
                      background-color: #2ecc71;
                      }
                      .btn-success.active {
                      color: #fff;
                      background-color: #2ecc71;
                      border-color: #2ecc71;
                      }

                      .btn-danger.btn {
                      color: #EE102B;
                      background-color: #fff;
                      border: 2px #EE102B solid;
                      }
                      .btn-danger.btn:hover {
                      color: #fff;
                      background-color: #EE102B;
                      }
                      .btn-danger.active {
                      color: #fff;
                      background-color: #EE102B;
                      border-color: #EE102B;
                      }
                      ")),

      # first radio button, it is green!
      radioGroupButtons("button1", label = "It's green !!", status = "success", choices=c("choice1"=50, "Choice2"=100, "Choice3"=150), selected=100),

      # second radio button, I wish it is red!
      radioGroupButtons("button2", label = "I wish I was red :( ...", status = "danger", choices=c("choice1"=1, "Choice2"=2), selected=1)
      ),
    mainPanel(plotOutput("distPlot"))
      )
    )

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM