Shiny selectInput CSS affecting all selectInputs - r

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

Related

Removing up/down arrows from numericInput() R Shiny

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.

How to better position Next/Back button in shiny glide, in order to eliminate large white space?

The Shinyglide package is just what I need, using a carousel for grouped radio buttons giving the user many choices for data parsing.
However, the "Next" (and "Back") button occupies a large white space. I'd like to shift the button in line with the glide row (see image at bottom). Does anyone know how to do this? Is there a CSS trick? Reading through the Glide manual, the only choices are "top" and "bottom".
If moving the Next/Back button isn't possible, a secondary option is to insert (a somewhat superfluous) line of text but in line with the Next/Back buttons, to at least cover up the annoyingly large white space.
The actual panel this is for has much more information presented than in this example, so I'm trying to make the page as clean as possible.
Please see image at bottom that better explains what I'm trying to do.
Reproducible example:
library(dplyr)
library(DT)
library(shiny)
library(shinyglide)
ui <-
fluidPage(
fluidRow(div(style = "margin-top:15px"),
strong("Input choices shown in row below, click ´Next´ to see more choices:"),
column(12, glide(
height = "25",
controls_position = "top",
screen(
div(style = "margin-top:10px"),
wellPanel(
radioButtons(inputId = 'group1',
label = NULL,
choiceNames = c('By period','By MOA'),
choiceValues = c('Period','MOA'),
selected = 'Period',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
),
screen(
div(style = "margin-top:10px"),
wellPanel(
radioButtons(inputId = 'group2',
label = NULL,
choiceNames = c('Exclude CT','Include CT'),
choiceValues = c('Exclude','Include'),
selected = 'Exclude',
inline = TRUE
),
style = "padding-top: 12px; padding-bottom: 0px;"
)
)
)
)
),
DTOutput("plants")
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)
You could use a custom control element with custom_controls, and then have it hover over the displayed screen on the top right with a container set to absolute positioning. Setting a limited width for the container will ensure that the back button won't fly too far out.
Something along these lines:
glide(custom_controls = div(class = "glide-controls", glideControls()), ...)
# Somewhere in the UI
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
)
Just make sure to also set controls_position = "bottom" so that the controls hover over the screen content, rather than under it.
A minimal example app:
library(shiny)
library(shinyglide)
ui <- fixedPage(
h3("Simple shinyglide app"),
tags$style(
".glide-controls { position: absolute; top: 18px; right: 15px; width: 160px; }"
),
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(wellPanel(p("First screen."))),
screen(wellPanel(p("Second screen.")))
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)

Horizontal Rule hr() in R Shiny Sidebar

You can normally make a horizontal rule under UI elements with hr() when using fluidRow() in Shiny, but you can't do it in a sideBarPanel() under text. How can I make a horizontal rule, or something else like it, to divide text and UI elements in my sidebar?
In general the line is visible, but with very low contrast to the background.
To make the line more visible you can modify the CSS code by including the following in the ui part:
tags$head(
tags$style(HTML("hr {border-top: 1px solid #000000;}"))
),
with tags$style(HTML(...)) you can include CSS in your app. The html tag for the line is hr. And the remaining parameter indicate specification of line choice, width, color, etc.
For a full working example see below:
library(shiny)
ui <- fluidPage(
tags$head(
tags$style(HTML("hr {border-top: 1px solid #000000;}"))
),
sidebarLayout(
sidebarPanel(
"text",
hr(),
uiOutput("out")
),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output) {
output$out <- renderUI({
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
})
}
shinyApp(ui = ui, server = server)
Update 12.2020:
Comment from David Ranzolin, see comment section.
You can also pass a style argument to hr() directly, e.g.: hr(style = "border-top: 1px solid #000000;")

R shiny: How to change the width of a progress-bar

How to edit the CSS to change the width of the progress-bar?
I put in
div.progress-bar{
width:100px
}
progress-bar{
width:100px
}
but it doesn't work.
Your bar has an Id = file1_progress so you can style that. Have a look at my example below, I set mine to 100px
rm(list = ls())
library(shiny)
ui <- fluidPage(
titlePanel("My R Shiny App"),
sidebarPanel(
fileInput('file', 'Choose file to upload.' ),width=3),
tags$style(type="text/css", "#file_progress { max-width: 100px; }")
)
server <- function(input, output, session) {}
shinyApp(ui, server)

R Shiny: UI Inputs format

It seems that this question applies to all shiny UI Inputs.
Specifically, I am trying to find a way to format selectInput. For example, how could I change the blue color which highlights the selection and the light blue shadow surrounding the box when selectInput is active.
The problem I am facing is that I am trying to format my shiny application via a css file which has a completely different colorset and that does not sit very well with the standard blue of all UI Inputs.
You can change the various attributes with CSS:
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput("variable", "Variable:",
c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear")),
tags$head(
tags$style(HTML(".selectize-input.input-active, .selectize-input.input-active:hover, .selectize-control.multi .selectize-input.focus {border-color: red !important;}
.selectize-dropdown .active {background: yellow !important;}"))
)
),
server = function(input, output) {
}
))

Resources