Transfer the CSS editing function from the user interface to the server in a Shiny application

Is there a way to dynamically change the color of input sliders globally?

I am familiar with using chooseSliderSkin from the shinyWidgets package to modify CSS and change colors. However, I am facing an issue where this only works in the UI section and not on the server side where it needs to access the input value for the desired color change.

When I execute the code below, the "Flat" skin is not applied correctly, resulting in unusual slider bar colors (though the labels display the right color). Additionally, the change only occurs once.

library(shinydashboard)
library(shiny)
library(shinyWidgets)

ui <- dashboardPage(
  dashboardHeader(
    title = "Title"),
  dashboardSidebar(
    radioGroupButtons(
      inputId = "switch",
      choices = c("Red"="true", "Blue"="false"),
      justified=TRUE
    ),
    sliderInput("abc", "abc", 0, 1, .5, .1),    
    sliderInput("def", "def", 0, 1, .5, .1)    
  ),
  
  dashboardBody( 
    uiOutput("slidercols")
  )
)

server <- function(input, output) {
  output$slidercols <- renderUI({
    chooseSliderSkin(skin="Flat", ifelse(input$switch=="true", "red", "blue"))
  }) 
}

shinyApp(ui, server)

This is how chooseSliderSkin typically functions (non-reactive):

library(shinydashboard)
library(shiny)
library(shinyWidgets)

ui <- dashboardPage(
  dashboardHeader(
    title = "Title"),
  dashboardSidebar(
    radioGroupButtons(
      inputId = "switch",
      choices = c("Red"="true", "Blue"="false"),
      justified=TRUE
    ),
    sliderInput("abc", "abc", 0, 1, .5, .1),    
    sliderInput("def", "def", 0, 1, .5, .1)  
  ),
  
  dashboardBody( 
    chooseSliderSkin(skin="Flat", "red")
  )
)

server <- function(input, output) { 
}

shinyApp(ui, server)

I am seeking a method to generalize this solution for other similar CSS-altering functions meant for the UI section.

Answer №1

Updating the functionality:

myCustomizeSlider <- function(style = c(
  "Shaded", "Flat", "Large", "Contemporary", "Sleek", "Circular", "Squared",
  "Appealing", "Basic", "Responsive"
), color = NULL) {
  style <- match.arg(arg = style)
  if(packageVersion("rstyled") > "1.5.0.9000" && 
     style %in% c("Appealing", "Basic", "Responsive")) {
    warning(paste0(
      "Style '", style,
      "' is outdated, please refer to ", 
      "http://ionden.com/a/plugins/ion.rangeSlider/skins.html ",
      "for alternate options."
    ))
    style <- "Flat"
  }
  cssTone <- NULL
  if (!is.null(color)) {
    stopifnot(length(color) == 1)
    if (style %in% c("Shiny", "Contemporary", "Responsive")) {
      cssTone <- tags$style(
        sprintf(
          ".irs-bar-edge, .irs-bar, .irs-single, .irs-from, .irs-to {background: %s !important;}",
          color
        ),
        if (style == "Contemporary") {
          sprintf(
            ".irs-from:after, .irs-to:after, .irs-single:after {border-top-color: %s !important;}",
            color
          )
        },
        if (style == "Contemporary") {
          sprintf(
            ".irs-from:before, .irs-to:before, .irs-single:before {border-top-color: %s !important;}",
            color
          )
        }
      )
    } else if (style == "Flat") {
      asb_ <- shinyWidgets:::asb("#ed5565", color)
      angle <- asb_[1]
      saturate <- asb_[2]
      brightness <- asb_[3]
      colImg <- paste0(
        ".irs-bar-edge, .irs-bar, .irs-single:after, .irs-from:after, .irs-to:after, .irs-slider",
        " {",
        "-webkit-filter: hue-rotate(", angle, "deg) saturate(",
        saturate, "%) brightness(", brightness, "%); ",
        "filter: hue-rotate(", angle, "deg) saturate(",
        saturate, "%) brightness(", brightness, "%);",
        "}"
      )
      cssTone <- tags$style(
        colImg,
        HTML(paste(
          ".irs-single, .irs-from, .irs-to, .irs-handle>i:first-child",
          sprintf(
            "{background: %s !important;}", color
          )
        )),
        HTML(paste(
          ".irs-single:before, .irs-from:before, .irs-to:before",
          sprintf(
            "{border-top-color: %s !important;}", color
          )
        ))
      )
    }
  }
  if (packageVersion("rstyled") > "1.5.0.9000") {
    tagList(
      cssTone,
      htmltools::htmlDependency(
        name = "ionrangeslider-skin",
        version = packageVersion("shinyWidgets"),
        package = "shinyWidgets",
        src = c(href = "shinyWidgets/ion-rangeslider", file = "assets/ion-rangeslider"),
        script = c("jquery.initialize.min.js", "custom-skin.js"),
        stylesheet = "ion.rangeSlider.min.css",
        head = sprintf(
          "<script type='custom-slider-tone'>{\"name\":\"%s\"}</script>", 
          tolower(style)
        )
      )
    )
  } else {
    tagList(
      cssTone,
      htmltools::attachDependencies(
        x = tags$div(),
        value = shinyWidgets:::sliderInputDep(style),
        append = FALSE
      )
    )
  }
}

Followed by:

  output$slidercols <- renderUI({
    color <- ifelse(input$switch, "red", "blue")
    myChooseSliderSkin(skin = "Modern", color)
  })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing the malfunction in the cloning of the carousel item?

My goal was to create a carousel that displays multiple images in one slide. However, I encountered an issue where once the fourth image is reached, the other three images are forcibly hidden. I want to give credit to the original creator of this code snip ...

How can I modify cell padding using a media query for a specific screen resolution?

In the desktop view, which is larger than 480px, I need a specific <td> to have a left-padding of 9px. However, once the resolution goes below 480px, this left-padding should increase to 18px. At the moment, my padding definition is specified within ...

Generate a graph using R and effortlessly showcase it in knitr

As I work with knitr, I aim to create an eps file in a figures/ folder everytime I run my rmd file. While browsing, I stumbled upon this useful question: Export a graph to .eps file with R that did exactly what I needed. However, the charts weren't di ...

Vertically align the text

Is there a way to center this text vertically within the divs? I've attempted adjusting the position using relative/absolute, and modifying the top and left properties of the paragraph, but none of these methods have been successful. div.roxo{ ...

Navigating to a precise location on initial page load using Angular 11

Within the structure of my app, I have a parent component that displays a large image from a child component. When the parent component loads, I want the browser window to automatically scroll to a specific position in order to center the image. Currently ...

Utilizing a resolved SAS macro variable in R operations

I am in the process of generating a PDF that involves a rather intricate journey. Initially, a SAS macro is used to create a .txt file, which is then imported into R and eventually transformed into the final PDF output. My goal is to execute my R program ...

Steps to display a variable in JavaScript on an HTML textarea

I'm working on a JavaScript variable called 'signature' var signature; //(Data is here) document.write(signature) Within my HTML document, I have the following: <div id="siggen"> <textarea id="content" cols="80" rows="10">& ...

hover effect with fading transition while mouse is still hovering

Is there a way to create a fade-in/fade-out effect on a div without the mouse needing to leave the area? Let me provide a clearer explanation: When the mouse enters the object The object gradually fades in Then, after a delay, the object fades out while ...

Inserting HTML code directly after a full-screen height responsive div while utilizing Bootstrap 4

So, I have three main components in my design: a navbar, a content div with sections, and a footer. I've managed to make the design responsive for the navbar and content div, but not for the footer yet. The issue lies with the content container, whi ...

Steps to keep the gridlines in the chart from moving

Take a look at the example provided in the following link: Labeling the axis with alphanumeric characters. In this particular instance, the gridlines adjust dynamically based on the coordinate values. How can we modify this so that the chart remains static ...

Having issues with Firefox rendering JavaScript and CSS correctly

I'm trying to figure out if it's the row class from Bootstrap that's causing issues, or if there's a problem with my JS/CSS not loading properly in Firefox. It seems to be working fine in Chrome and Safari. Any ideas on what could be go ...

What are some techniques for concealing a CSS transition beneath another element in both directions?

Witness the magic in action! By clicking on the black box below, a larger black box will gracefully emerge from beneath the sidebar. While it may not be as clear in jsfiddle, rest assured that this effect is more pronounced in browsers. Thanks to some clev ...

Use desktop images to set the background for mobile views in a React JSX environment

My custom Gutenberg block is built using React JSX, allowing users to input two hero images - one for Desktop and one for Mobile. Currently, if a user does not upload a mobile image, it displays a blank space. I am looking for a way to have the desktop ima ...

Aligning the text in the middle of a button

Currently delving into Front-End development and in the process of coding my maiden site using bootstrap. Encountered a roadblock on something seemingly simple. How can I center text within a button? Here's the button, the default one utilizing an " ...

Is there a way to eliminate the additional and varying pseudo-padding on text inputs in both Webkit and Gecko browsers?

The issue I'm facing is specific to input[type="text"] elements in Webkit. No matter what adjustments I make, it seems like there is an additional padding: 1px 0 0 1px (top and left only) applied to the element. A similar anomaly occurs in Gecko as w ...

Using jQuery, locate identical text and assign a class to the corresponding container

How can I check if any of the h2 elements match the text in h1, ignoring case sensitivity? If a match is found, I want to add a class to the container Product-div. <div id="PageHeader"> <h1>Same text</h1> </div> <div class= ...

Can the card overlay slide appear solely on top of the image?

I am trying to create a gallery section of cards using Bootstrap 4 where I want the user to hover over each card and have an overlay slide or fade in, covering only the image. Currently, the overlay slides in over the entire card instead. I have been stru ...

What is the best way to relocate a form to the top of the page

I am creating a website to enhance my HTML skills, and I encountered an issue with the sign-in form. Whenever I try to place an image next to the form, it automatically moves to the bottom. I have attempted using padding-top and padding-bottom but to no av ...

How can I alter the color of the menu text when scrolling to the top of a webpage?

As I navigate my website, I encounter a menu with a transparent background at the top that changes to black as I scroll down. On a specific page where the background is white, this presents an issue: when the menu reaches the top, the white background clas ...

The font size calculation is larger than the CSS definition on the Asus Nexus 7 device

Running the website on an Asus Nexus 7 (developed in jQueryMobile), I set the font size in CSS to be 14px. However, while debugging using Chrome on my PC, I noticed that the computed size is actually 22px. Here's a snippet of the HTML code: <div ...