I have a sidebarPanel in my shiny ui that contains 5 switchInputs, each of which are preceded by a piece of inline text with varying lengths. The latter two switchInputs trigger a conditional numeric input, which works fine. Because the length of the inline text varies, I want to align the switchInput boxes to the right of the sidebarPanel. I want to achieve something like this:
I have tried doing so by using style="float:right"
within each div()
that contains a switchInput. However, for some reason this only works for the top switchInput as the lower ones are shifted to the left. When the conditionalPanel of the fourth switchInput is triggered, this nonetheless seems to correctly 'reset' the alignment of the switchInput below (see image below). Any ideas on achieving the above layout?
Here's my code:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
div(style = "white-space: nowrap;",
h5('Yes or no?',style="display:inline-block"),
div(style="display: inline-block;float:right;",
switchInput("switch1", onLabel="Yes", offLabel="No", size="mini",value=FALSE))
),
div(style = "white-space: nowrap;",
p("Hey there, having a good day?",style="display:inline-block"),
div(style="display: inline-block;float:right;",
switchInput("switch2", onLabel="Yes", offLabel="No", size="mini",value=FALSE))
),
div(style = "white-space: nowrap;",
h5("Would you like some apples?",style="display:inline-block"),
div(style="display:inline-block; float:right",
switchInput("switch3", onLabel="Yes", offLabel="No", size="mini",value=FALSE))
),
div(style = "white-space: nowrap;",
p("Have you ever had a fish tank at home?",style="display:inline-block"),
div(style="display: inline-block; float:right",
switchInput("switch4", onLabel="Yes", offLabel="No", size="mini",value=FALSE))
),
conditionalPanel(
condition = "input.switch4 == true",
numericInput("numeric1", label = "If so, how many fish did it contain?", value = 300)
),
div(style = "white-space: nowrap;",
h5("Have you ever flown an airplane?",style="display:inline-block"),
div(style="display: inline-block; float:right",
switchInput("switch5", onLabel="Yes", offLabel="No", size="mini",value=FALSE))
),
conditionalPanel(
condition = "input.switch5 == true",
numericInput("numeric2", label = "If so, how many flights?", value = 2.5)
),
),
mainPanel()
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)
My recommendations:
Use flexbox `display: flex; justify-content: space-between;" would do the job
Avoid using inline css, consider adding classes to your elements and styling those. read more
Try to reduce code duplication, it would make it easier to refactor in the future. You can do this by creating a function. read more
Here is the code
library(shiny)
library(shinyWidgets)
switch_container <- function(input_id, label) {
div(
class = "switch-container",
label,
switchInput(
input_id,
onLabel = "Yes",
offLabel = "No",
size = "mini",
value = FALSE)
)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
tags$style(".switch-container {display: flex; justify-content: space-between;}"),
switch_container("switch1", h5("Yes or no?")),
switch_container("switch2", p("Hey there, having a good day?")),
switch_container("switch3", h5("Would you like some apples?")),
switch_container("switch4", p("Have you ever had a fish tank at home?")),
conditionalPanel(
condition = "input.switch4 == true",
numericInput("numeric1", label = "If so, how many fish did it contain?", value = 300)
),
switch_container("switch5", h5("Have you ever flown an airplane?")),
conditionalPanel(
condition = "input.switch5 == true",
numericInput("numeric2", label = "If so, how many flights?", value = 2.5)
),
),
mainPanel()
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)