I am trying to get a simple column-based layout for a card in bslib, but I am not getting the expected results. The example app (see below) has two columns for ui elements in a card: the first column is always the same, and the ui elements in the second depend on the selection in the selectInput on the first column (using two conditionalPanels). When the first element is selected in ‘planningType’ the second column starts in the top, but if the second element is chosen, then the second column ui element has a top margin (an empty space), that I can’t get rid of. I tried using fill = FALSE and fillable = FALSE in the card_body and layout_column_wrap, but it didn’t make a difference. Is there something that can be done? Thanks a lot.
library(shiny)
library(bslib)
ui <- page_fluid(
title = "Habit planner",
card(
card_header("General planning", class = "bg-primary"),
card_body(
layout_column_wrap(
width = 1/2,
# First column
selectInput("planningType",
label = "Type of planning",
choices = c("Menu" = "menu",
"Physical activity" = "physical"),
selected = "Menu"),
# Second column
layout_column_wrap(
width = 1,
conditionalPanel("input.planningType == 'menu'",
selectInput("diet",
label = "Type of diet",
choices = c("Mediterranean",
"Low calory",
"Mixed"),
selected = "Mediterranean"),
selectInput("groceries",
label = "Where do you want to buy food?",
choices = c("Town market",
"Supermarket"),
selected = "Mediterranean")
),
conditionalPanel("input.planningType == 'physical'",
selectInput("activity",
label = "Type of activity",
choices = c("Running",
"Strength training",
"Swimming"),
selected = "Running")
)
)
)
)
)
)
server <- function(input, output) { }
shinyApp(ui = ui, server = server)
That's an odd error, but perhaps it's because it's experimental? Not sure. It's pretty easy to fix though—all you need to do is tag the two conditions together, e.g., the div()
tag.
The next problem you'll run into is the dropdowns disappearing behind the card. You can address that with using selectizeInput
and setting the option dropdownParent = 'body'
. (versus selectInput
-- both of which use selectize.js
in the background)
Here's a simple example of how you can make this obey your commands.
library(shiny)
library(bslib)
ui <- page_fluid(
title = "Habit planner",
card(
card_header("General planning", class = "bg-primary"),
card_body(
layout_column_wrap(
width = 1/2,
# First column
selectizeInput("planningType",
label = "Type of planning",
choices = c("Menu" = "menu",
"Physical activity" = "physical"),
selected = "Menu",
options = list(dropdownParent = 'body')), # I'm new
# Second column
layout_column_wrap(
width = 1,
div( # <----------- I'm new
conditionalPanel("input.planningType == 'menu'",
selectizeInput("diet",
label = "Type of diet",
choices = c("Mediterranean",
"Low calory",
"Mixed"),
selected = "Mediterranean", # I'm new
options = list(dropdownParent = 'body')),
selectizeInput("groceries",
label = "Where do you want to buy food?",
choices = c("Town market",
"Supermarket"),
selected = "Mediterranean", # I'm new
options = list(dropdownParent = 'body'))
),
conditionalPanel("input.planningType == 'physical'",
selectizeInput("activity",
label = "Type of activity",
choices = c("Running",
"Strength training",
"Swimming"),
selected = "Running", # I'm new
options = list(dropdownParent = 'body'))
)
)
)
)
)
)
)
server <- function(input, output) { }
shinyApp(ui = ui, server = server)