How to globally supply css to each radioGroupButtons widget in a shiny app

Issue

I have this minimal example adapted from here R shiny radiogroup Button change color:

library(shiny)

  ui = fluidPage(
    radioGroupButtons(
     # status = "primary ",  ##  you can change status value to change to select few colors
      inputId = "a",
      checkIcon = list(yes = icon("check")),
      choiceValues = 0:3,
      choiceNames = paste0(0:3),
      justified = TRUE, width = "300px"
    ),
    tags$script("$(\"input:radio[name='a'][value=0]\").parent().css('background-color', '#7EF373');"),
    tags$script("$(\"input:radio[name='a'][value=1]\").parent().css('background-color', '#E7E7E7');"),
    tags$script("$(\"input:radio[name='a'][value=2]\").parent().css('background-color', '#EDB6B2');"),
    tags$script("$(\"input:radio[name='a'][value=3]\").parent().css('background-color', '#DE6B63');"),
    
    radioGroupButtons(
      # status = "primary ",  ##  you can change status value to change to select few colors
      inputId = "b",
      checkIcon = list(yes = icon("check")),
      choiceValues = 0:3,
      choiceNames = paste0(0:3),
      justified = TRUE, width = "300px"
    ),
    tags$script("$(\"input:radio[name='b'][value=0]\").parent().css('background-color', '#7EF373');"),
    tags$script("$(\"input:radio[name='b'][value=1]\").parent().css('background-color', '#E7E7E7');"),
    tags$script("$(\"input:radio[name='b'][value=2]\").parent().css('background-color', '#EDB6B2');"),
    tags$script("$(\"input:radio[name='b'][value=3]\").parent().css('background-color', '#DE6B63');")
    )
  server = function(...) {}

  shinyApp(ui, server)

It basically colors the grouped radio buttons.

I would like to apply this colors to each radioGroupButtons Widget without using the four rows again and again.

I tried doing it with a css file in the parent directory but I don’t know how to write the four rows in css e.g.

How to write:

 tags$script("$(\"input:radio[name='a'][value=0]\").parent().css('background-color', '#7EF373');"),
    tags$script("$(\"input:radio[name='a'][value=1]\").parent().css('background-color', '#E7E7E7');"),
    tags$script("$(\"input:radio[name='a'][value=2]\").parent().css('background-color', '#EDB6B2');"),
    tags$script("$(\"input:radio[name='a'][value=3]\").parent().css('background-color', '#DE6B63');"),

in the .css file and use it in the radioGroupButtons widget?

Solution

tags$script is used to run some JavaScript code, this is not some CSS code (tags$style is used for CSS).

The first part of this code:

$(\"input:radio[name='a'][value=0]\").parent().css('background-color', '#7EF373');

i.e. $(\"input:radio[name='a'][value=0]\") selects one or more HTML elements. Namely, it targets all radio inputs with a name attribute equal to 'a' and a value attribute equal to 0. You can drop the part [name='a'] so that the other radio group is selected.

If you want to put this code in an external file, create a .js file in the www subfolder containing this code:

$(document).ready(function() {
  $("input:radio[value=0]").parent().css('background-color', '#7EF373');
  $("input:radio[value=1]").parent().css('background-color', '#E7E7E7');
  $("input:radio[value=2]").parent().css('background-color', '#EDB6B2');
  $("input:radio[value=3]").parent().css('background-color', '#DE6B63');
});

then include this file in your app by adding this code in the UI:

tags$head(tags$script(src = "yourJSfile.js")),

See here for more information about selection by attribute value.

You could also proceed as follows:

$(document).ready(function() {
  $("input:radio").each(function() {
    var value = $(this).attr("value");
    var color;
    switch(value) {
      case 0:
        color = "#E7E7E7";
        break;
      case 1:
        color = "#EDB6B2";
        break;
      case 2:
        color = "#AAAAAA";
        break;
      case 3:
        color = "#DE6BB3";
    }
    $(this).parent().css('background-color', color);
  });
});

Or if you want to target only these two radio groups:

$(document).ready(function() {
  $("input:radio").each(function() {
    var name = $(this).attr("name");
    if(name === "a" || name === "b") {
      var value = $(this).attr("value");
      var color;
      switch(value) {
        ......
      }
      $(this).parent().css('background-color', color);
    }
  });
});

Answered By – Stéphane Laurent

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published