how to make the radio buttons "side by side" in shiny - css

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

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)

How to specify different radiobutton with different styles in shiny?

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)

Shiny selectInput CSS affecting all selectInputs

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

Loading screen and navbarPage

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")
}
)

Resources