How to vertically justify R Shiny radioButtons - r

Any guidance please on how to arrange the buttons in the app below into a neat straight line while still inheriting the ‘center’ alignment from the column? I am looking to keep the column’s ‘centre’ alignment so that the buttons line up under the “Center Aligned Title”, however this then lines up each choice in an erratic manner, dependent on the length of the choice.
library(shiny)
app <- shinyApp(
ui = fluidPage(
column(4),
column(4,
fluidRow(
column(12,
align = 'center',
h6('Center Aligned Title')
)
),
fluidRow(
column(12,
align = 'center',
# align = 'left', # This justifies/arranges the buttons neatly
# but not underneath "Center Aligned Title"
radioButtons(
inputId = 'my_btns',
label = NULL,
choices = c('abc','defg','hijllm','no'),
selected = character(0),
inline = F
)
)
)
),
column(4)
),
server = function(input, output) {}
)
runApp(app)

You could drop align = 'center' in the second column() and use CSS to align the radio buttons in a flexbox like this:
app <- shinyApp(
ui = fluidPage(
tags$head(
tags$style(HTML("
#my_btns, #my_div {
display: flex;
justify-content: center;
}"
))
),
fluidRow(
column(12,
align = 'center',
h6('Center Aligned Title')
)
),
fluidRow(
column(12,
div(
radioButtons(
inputId = 'my_btns',
label = NULL,
choices = c('abc','defg','hijllm','no'),
selected = character(0),
inline = F
), id = "my_div")
)
)
),
server = function(input, output) {}
)
Result:

Related

how to align tabsetpanel "pills" center in R shiny

I am trying to center-align tabsetpanel "pills" on shiny, but it alwais get on left position. Here is the code example, anyone knows how to align this buttons or pills center?
library(shiny)
ui <- fluidPage(
tabPanel(title = "Hello world", value = "HB",
tabsetPanel(id="subtabs", type="pills",
tabPanel(title = "TAB 1", value = "ILPF",
br(),
h4("I like Pink floyd, my favourite album is 'The dark side of the moon'", style = "color:grey", align = "center"),
br()
),
tabPanel(title = "TAB 2", value = "FS",
br(),
h4("But my favourite song is 'Shine on you crazy diamond'", style = "color:grey", align = "center"),
br()
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)
The pills should be in the middle of the page
You can do so by adding some CSS to your app. tags$style('ul.nav-pills{display: flex !important;justify-content: center !important;}') does the trick.
library(shiny)
ui <- fluidPage(
tags$head(
tags$style('
ul.nav-pills{
display: flex !important;
justify-content: center !important;
}')
),
tabPanel(title = "Hello world", value = "HB",
tabsetPanel(id="subtabs", type="pills",
tabPanel(title = "TAB 1", value = "ILPF",
br(),
h4("I like Pink floyd, my favourite album is 'The dark side of the moon'", style = "color:grey", align = "center"),
br()
),
tabPanel(title = "TAB 2", value = "FS",
br(),
h4("But my favourite song is 'Shine on you crazy diamond'", style = "color:grey", align = "center"),
br()
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)

How to replace fluidRow with a horizontally scrollable non-wrapping row in tab panel?

The reproducible code below uses a fluidRow() to house several user selections using radio buttons. Works fine in this limited example of only 2 radio button groupings. But I need to fit more radio button groupings into this row, without any wrapping. To do this, I'd like to replace this combination of fluidRow()/column() with a horizontally scrollable, non-wrapping row that is not subject to the limitations of the 12-wide grid system currently used in this code.
Also, all objects viewed in the scrolling row need to be left aligned without "fluid" expansion. Currently, using this fluidRow()/column() combo, if the viewing pane is expanded, the 2 columns housing each radio button grouping also expanded which doesn't look good. They need to remain fixed width and stay to the left.
Is this possible?
I prefer sticking with this sidebar/main panel/tab panel/conditional panel layout as I find it very user friendly for navigating the type of data we work with.
The image at the bottom further explains.
Reproducible code:
library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
ui <-
fluidPage(
titlePanel("Summary"),
sidebarLayout(
sidebarPanel(
selectInput("selectData", h5("Select data to view:"),
choices = list("Beta"),
selected = "Beta"),
),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
conditionalPanel(condition = "input.selectData == 'Beta'",
fluidRow(div(style = "margin-top:15px"),
column(width = 6, offset = 0,
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;"
)
),
column(width = 6, offset = 0,
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")
)
),
id = "tabselected"
)
)
)
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)
How about using a carousel instead e.g. via shinyglide or slickR:
library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
library(shinyglide)
ui <-
fluidPage(
titlePanel("Summary"),
sidebarLayout(
sidebarPanel(
selectInput("selectData", h5("Select data to view:"),
choices = list("Beta"),
selected = "Beta"),
),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
conditionalPanel(condition = "input.selectData == 'Beta'",
fluidRow(div(style = "margin-top:15px"),
column(12, glide(
height = "25",
controls_position = "top",
screen(
p(strong("Group 1")),
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(
p(strong("Group 2")),
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")
)
),
id = "tabselected"
)
)
)
)
server <- function(input, output, session) {
output$plants <- renderDT({iris %>% datatable(rownames = FALSE)})
}
shinyApp(ui, server)

Center form below table in R Shiny

I wish to center a small form below a table that is also centered.
I center the table using, fluidRow and column like so:
fluidRow(
column(12, align="center", reactableOutput("table")),
),
If I do the same with the form, each component of the form becomes centered in the page which is wrong. How do I center a correct looking form beneath the centered table?
Example Code
library(shiny)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align="center", reactableOutput("table")),
),
fluidRow(
column(12,
div(id = "form",
textInput("email", "Email", width = "250px", placeholder = "joe#example.com"),
radioButtons(inputId = "pref",
label ="Here's a label:",
choiceNames = list(
"First choice",
"Second choice"),
choiceValues = list(
"v1", "v2"
)),
actionButton("submit", "Enter", class = "btn-primary", width = 250,
style="color: #FFF; background-color: #132EBA;"),
)
)
)
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
fullWidth = FALSE)
})
observeEvent(input$submit, {
# Do something!
})
}
shinyApp(ui, server)
You need to create 2 div elements and give them CSS properties :
first one is centered
second one is an inline-block and aligned left
Source : CSS: Center block, but align contents to the left
So it gives
library(shiny)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align="center", reactableOutput("table")),
),
fluidRow(
column(12,
div(id = "form",
style = "text-align: center;",
div(
id = "form_content",
style = "display:inline-block; text-align: left;",
textInput("email", "Email", width = "250px", placeholder = "joe#example.com"),
radioButtons(inputId = "pref",
label ="Here's a label:",
choiceNames = list(
"First choice",
"Second choice"),
choiceValues = list(
"v1", "v2"
)),
actionButton("submit", "Enter", class = "btn-primary", width = 250,
style="color: #FFF; background-color: #132EBA;")
)
)
)
)
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
fullWidth = FALSE)
})
observeEvent(input$submit, {
# Do something!
})
}
shinyApp(ui, server)

Shiny navbarPage combined with fluidRow

I'm having some trouble with setting out the layout of my shiny app. After trying a couple of different options the one to work the best for me was the navbarPage. Although, I managed to solve the majority of my problems(with the help of stackoverflow) I'm stuck in one.
Basically, I have a table that has many columns and it ends up always larger than the wellPanel that contains the table.
Below is some code to illustrate the problem:
require(shiny)
require(shinythemes)
side_width <- 5
sidebar_panel <-
sidebarPanel(
width = side_width,
radioButtons("Radio1",
label = h4("Radio label 1"),
choices = list("Europe" = "EU",
"USA" = "US"),
selected = "EU"),
hr()
br()
radioButtons("Radio 2",
label = h4("Radio label 2"),
choices = list("Annual" = 1, "Monthly" = 12),
selected = 1)
)
main_panel <- mainPanel(
width = 12 - side_width,
wellPanel(
h5(helpText("Figure 1: ..."))
),
wellPanel(
h5(helpText("Table 1: ..."))
),
wellPanel(
h5(helpText("Table 2: ..."))
),
wellPanel(
fluidRow(
column(12,
h5(helpText("Table 3: ..."))
)
)
)
)
# user interface
ui <- shiny::navbarPage("testing shiny",
tabPanel("Tab1",
sidebarLayout(
sidebarPanel = sidebar_panel,
mainPanel = main_panel,
position = "left")
),
tabPanel("Tab2",
verbatimTextOutput("summary")
),
tags$style(type="text/css", "body {padding-top: 70px;}"),
theme=shinytheme("cosmo"),
position ="fixed-top"
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
When you run the code you will see the current layout. All would be fine if it wasn't for that massive wide table 3 which half of it is always out of the wellPanel.
My question is is it possible to extend the wellPanel to the left so it occupies the entire width of the layout?
Any pointers are highly appreciated.
Cheers
The fluidRow and column functions don't do anything inside the wellPanel/mainPanel - you want to put this particular wellPanel as its own fluidRow separate from the sidebar layout.
Additionally, if your table is being made in the DT package, you can add scrollX=TRUE to the render options so that it'll add a scroll bar if the table is too big to fit.
require(shiny)
require(shinythemes)
side_width <- 5
# user interface
ui <- navbarPage(
"testing shiny",
tabPanel("Tab1",
sidebarLayout(position = "left",
sidebarPanel(width = side_width,
radioButtons("Radio1",
label = h4("Radio label 1"),
choices = list("Europe" = "EU",
"USA" = "US"),
selected = "EU"),
hr(),
br(),
radioButtons("Radio 2",
label = h4("Radio label 2"),
choices = list("Annual" = 1, "Monthly" = 12),
selected = 1)),
mainPanel(
width = 12 - side_width,
wellPanel(
h5(helpText("Figure 1: ..."))
),
wellPanel(
h5(helpText("Table 1: ..."))
),
wellPanel(
h5(helpText("Table 2: ..."))
)
)
),
fluidRow(
column(12,
wellPanel(
h5(helpText("Table 3: ..."))
)
)
)
),
tabPanel("Tab2",
verbatimTextOutput("summary")),
tags$style(type = "text/css", "body {padding-top: 70px;}"),
theme = shinytheme("cosmo"),
position = "fixed-top"
)

Label next to selectInput in shiny

I've got a shiny application like this:
server.R:
library(shiny)
function(input, output) { NULL }
and ui.R:
library(shiny)
pageWithSidebar(
headerPanel("side-by-side"),
fluidRow(
column(2),
column(4,
wellPanel(
selectInput(inputId = "options", label = "some text",
choices = list(a = 0, b = 1)))
)
),
fluidRow(
h3("bla bla")
)
)
And I would like to have the label of selectInput next to it, not above. Do you know how to do it?
I've found this: Positioning Shiny widgets beside their headers
but it doesn't work for me.
There's multiple ways of doing this, here's one:
library(shiny)
server <- shinyServer(function(input, output) { NULL })
ui <- shinyUI(
pageWithSidebar(
headerPanel("side-by-side"),
sidebarPanel(
fluidRow(
tags$head(
tags$style(type="text/css", "label.control-label, .selectize-control.single{ display: table-cell; text-align: center; vertical-align: middle; } .form-group { display: table-row;}")
),
column(2),
column(4,
selectInput(inputId = "options", label = "some text",
choices = list(a = 0, b = 1))
)
)),
mainPanel(
fluidRow(
h3("bla bla")
))
)
)
shinyApp(ui=ui,server=server)
If you don't want to mess with shinys default CSS you can just leave the label empty and create a label next to it instead of forcing the existing label to the side.

Resources