I am trying to develop a shiny app that contains several panels and each panel has some radio buttons. My current problem is: when I try to specify a certain radio button's style like the below codes, the CSS automatically applies to other radio buttons in whole app.
fluidRow(column(12, align='center',h4(tags$style(HTML(".radio-inline {margin-right: 200px;}"))),
radioButtons("MPL1",label="",choiceNames=c("(60, 0; 12, 1)","(56, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T))),
Some people mention I need to use #inputID, but this trick does not work for my case. After I replace ".radio-inline" with "#MPL1", the codes are invalid (the app can be opened, but the buttons is of the default style).
fluidRow(column(12, align='center',h4(tags$style(HTML("#MPL1 {margin-right: 200px;}"))),
radioButtons("MPL1",label="",choiceNames=c("(60, 0; 12, 1)","(56, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T))),
Could you please tell me where I make mistakes? Any help would be welcome. Thank you very much!
WU
You can specify a class inside a div(). Then this affects all items defined with that class.
Try this
ui <- fluidPage(
fluidRow(column(12, align='center',
div(class="MPL", radioButtons("MPL1",label="",choiceNames=c("(60, 0; 12, 1)","(56, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T)))),
fluidRow(column(12, align='center', h4(tags$style(HTML(".radio-inline {margin-right: 100px;}"))),
radioButtons("MPL2",label="",choiceNames=c("(61, 0; 12, 1)","(55, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T))),
fluidRow(column(12, align='center',h4(tags$style(HTML(".MPL .radio-inline {margin-right: 300px;}"))),
div(class="MPL", radioButtons("MPL3",label="",choiceNames=c("(62, 0; 12, 1)","(54, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T)) ) ),
fluidRow(column(12, align='center',
radioButtons("MPL4",label="",choiceNames=c("(63, 0; 12, 1)","(53, 0; 48, 1)"),
choiceValues=c(0,1),selected= character(0),inline=T)))
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)
Related
I am interested in removing or hiding the side arrows that appear when you use numericInput() with shiny. I will attach an image of the arrows that I am referring to so everyone can understand which part I would like to remove/hide. After reading the documentation, it does not appear that there is an option to remove these arrows. So I am wondering if there is a way to use CSS to remove these arrows. I did see one other post that asked a similar question. However, I am only interested in using numericInput().
I will attach some sample code. The code essentially does nothing but it will give you a reproducible example.
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
WARNING: I have read online that the side arrows do not show up on all web browsers and some versions of RStudio. See here
It does not appear that there is a way to remove the arrows from a numericInput(), however, there is a way to hide them. Just to be clear there is a difference between removing and hiding. Removing the arrows, in theory, should completely remove the code for the arrows. Hiding the arrows will simply mask the code for the side arrows, however, the code will still be present but will not be seen by the user unless they inspect the page.
Below is CSS that can be used to hide the side arrows from numericInput().
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
)
If you wanted to apply this code to the example given in the question, then you could do something like this
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
),
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
Overall this is just a workaround because there is no option to remove the side arrows.
I am trying to create a shiny app that contains a series of double-radio-button questions. The relevant codes are as below:
fluidRow(column(12, align='center',h4(tags$style(HTML(".radio-inline {margin-right: 200px;}"))), radioButtons("MPL1",label="",choiceNames=c("(60, 0; 12, 1)","(56, 0; 48, 1)"), choiceValues=c(0,1),selected= character(0),inline=T))),
It works, but I am stuck with adjusting the locations of the buttons. As the below figure shows, the default setting always puts the button at the left-hand side of its label, while I am trying to put the buttons against each other.
Could you please tell me how to achieve my expectation? Besides, it would be very lovely if you could tell me how I can systematically study css setting. I am eager to be an expert in making shiny apps. Thank you very much.
Best,
J
Here you go. I added two more rules to make this happen.
library(shiny)
ui <- fluidPage(
fluidRow(
column(12, align='center',
tags$style(HTML(
"
.radio-inline {margin-right: 200px;}
.radio-inline:nth-of-type(odd) > span {
padding-right: 25px;
}
.radio-inline:nth-of-type(odd) > input {
position: absolute;
right: 0;
}
"
)),
radioButtons(
"MPL1", label="",
choiceNames=c("(60, 0; 12, 1)","(56, 0; 48, 1)"),
choiceValues=c(0,1),
selected= character(0),
inline=TRUE
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
To learn CSS, use W3 school
Shiny makes use of the ion-rangeslider. I figured out how to modify some of its attributes. The code below changes the button color and the background color of the label above the button, and also removes the slider bar. I need to make additional changes, but am not sure which other slider attributes I can change--and how they should be referred to.
Is there a comprehensive list of this slider's attributes (such as ".irs-slider") and their properties? (E.g., for the attribute .irs-slider: "width"; "height"; "top"; "background", etc.)
Update: GJPLatten's suggestion to right-click the slider in the browser and select "Inspect Element" saved my day. However, I'm still interested in finding a comprehensive list of attribute and property names which also provides descriptive information, since this would be easier to navigate and work with.
library(shiny)
ui <- fluidPage(
sliderInput("default",
"Default slider",
min = 0,
max = 50,
value = 20),
sliderInput("modified",
"Modified slider",
min = 0,
max = 50,
value = 20),
tags$style(type = "text/css",
HTML(".js-irs-1 .irs-slider { width: 8px; height: 20px; top: 20px; background: green }",
".js-irs-1 .irs-bar { display: none }",
".js-irs-1 .irs-bar-edge { display: none }",
".js-irs-1 .irs-single { color: black; background: transparent }"))
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
The parts within the HTML() function are all css. W3schools have a great tutorial on this at https://www.w3schools.com/css/default.asp. You can get the element name by right clicking on the element in your browser and clicking inspect element.
I have the following css above a selectizeInput so that selected items are coloured alternatively making for better readability.
tags$style(HTML(".item:nth-child(odd) {background: #F4F4F4 !important;
width: 100% !important;}
.item:nth-child(even) {background: white !important;
width: 100% !important;}"))
Unfortunately it is affect all other selectizeInputs and selectInputs no matter where on the dashboard they appear.
How can I have the above css only apply to the one selectizeInput.
Thanks
I think getting the CSS to select the proper <div> is the trick. Here's a reproducible example of the functionality using the default Shiny scaffolding:
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Control CSS of Singl Selectize Input"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
tags$style(HTML("#bins+ .selectize-control.multi .selectize-input > .item:nth-child(odd) {background: #F4F4F4 ;
width: 100% !important;}
#bins+ .selectize-control.multi .selectize-input > .item:nth-child(even) {background: white ;
width: 100% !important;}")),
selectizeInput("bins",
"Number of bins:",
choices = c(1:50),
selected = 30,
multiple = TRUE),
selectizeInput("newbins",
"Number of bins:",
choices = c(1:50),
selected = 30,
multiple = TRUE)
),
# Show a plot of the generated distribution
mainPanel(
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)
The CSS first finds the right id then finds the correct div below that using class. More info on the + sign in CSS: https://www.w3schools.com/cssref/sel_element_pluss.asp
I try to make a loading screen as in this nice example http://daattali.com:3838/loading-screen/. Unfortunately I cannot figure out how to do exactly the same effect with 'navbarPage'.
In this slightly modified app below there are two tab panels called "start" and "end". When the app starts none of the tab panels are active. One have to quickly click on the first tab to see the loading screen but this is not what I would like. Is there a way to make it so quick and easy as in the mentioned example?
Thank you for the help!
library(shinyjs)
appCSS <- "
#loading-content {
position: absolute;
background: #000000;
opacity: 0.9;
z-index: 100;
left: 0;
right: 0;
height: 100%;
text-align: center;
color: #FFFFFF;
}
"
shinyApp(
ui = navbarPage(
useShinyjs(),
inlineCSS(appCSS),
tabPanel(title = "Start",
# Loading message
div(
id = "loading-content",
h2("Loading...")
),
# The main app code goes here
div(
id = "app-content",
p("This is a simple example of a Shiny app with a loading screen."),
p("You can view the source code",
tags$a(href = 'https://github.com/daattali/shiny-server/blob/master/loading-screen',
"on GitHub")
)
)
),
tabPanel(title = "End",
h2("Second tab"))
),
server = function(input, output, session) {
# Simulate work being done for 1 second
Sys.sleep(2)
# Hide the loading message when the rest of the server function has executed
hide(id = "loading-content", anim = TRUE, animType = "fade")
}
)
EDIT: The original link to the loading screen app has been taken down. It can now be accessed on github here
Well, I believe that you will enjoy with this solution but it is not perfect. The key is the tagList, you can add whatever you want before the navbar.
Furthermore I add the padding to your CSS code and now, there is a title in the navbar.
Unfortunately the navbarPage is not possible to hide of a not complex way.
library(shiny)
library(shinyjs)
appCSS <- "
#loading-content {
position: absolute;
padding: 10% 0 0 0;
background: #000000;
opacity: 0.9;
z-index: 100;
left: 0;
right: 0;
height: 100%;
text-align: center;
color: #FFFFFF;
}
"
shinyApp(
ui =
tagList(
useShinyjs(),
inlineCSS(appCSS),
# Loading message
div(
id = "loading-content",
h2("Loading...")
),
navbarPage("Test",
tabPanel(title = "Start",
# The main app code goes here
div(
id = "app-content",
p("This is a simple example of a Shiny app with a loading screen."),
p("You can view the source code",
tags$a(href = 'https://github.com/daattali/shiny-server/blob/master/loading-screen',
"on GitHub")
)
)
),
tabPanel(title = "End",
h2("Second tab"))
) #close navbarPage
), #close tagList
server = function(input, output, session) {
# Simulate work being done for 1 second
Sys.sleep(5)
# Hide the loading message when the rest of the server function has executed
hide(id = "loading-content", anim = TRUE, animType = "fade")
}
)