Goal
I want to place a selectInput
and an actionButton
side by side in the footer of my shinydashboard::box
. The button should be "relatively close" to the selectInput
irrespective of the width of the box.
What I have tried so far
So far I tried column
, splitLayout
or styling via display: inline-block
, but I am not happy with either of the solutions:
column
: depending on the width of the box, the gap between selectInput
and actionButton
is too big (I could partially solve that by extending the selectInput
width to 100%, but then the width is too large)splitDesign
: best option so far, but cellWidths
needs adaptation based on box width
and works also only with 100% selectInput
width and for big boxes, the width of the second split seems to be too biginline-block
: does not play well with the general CSS
Example
library(shiny)
library(purrr)
library(shinydashboard)
widths <- c(1, 2,3, 4, 6, 12)
makeBoxes <- function(width, method = c("split", "col", "css")) {
method <- match.arg(method)
split <- function(width, count) {
splitLayout(selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS,
width = "100%"),
actionButton(paste("ab", width, count, sep = "_"), icon("trash")),
cellWidths = c("87.5%", "12.5%"),
cellArgs = list(style = "vertical-align: top"))
}
col <- function(width, count) {
fluidRow(column(width = 11,
selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS,
width = "100%")),
column(width = 1,
actionButton(paste("ab", width, count, sep = "_"), icon("trash"))))
}
css <- function(width, count) {
fluidRow(div(selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS),
style = "display: inline-block; vertical-align: top"),
actionButton(paste("ab", width, count, sep = "_"), icon("trash")))
}
wrap <- function(method, ...)
switch(method, split = split(...), col = col(...), css = css(...))
map(seq(1, 12 / width, 1), function(count)
box(solidHeader = TRUE, title = "Box", status = "info", width = width,
footer = wrap(method, width, count)))
}
server <- function(input, output) {
}
ui1 <- dashboardPage(dashboardHeader(), dashboardSidebar(),
dashboardBody(map(widths, ~ fluidRow(makeBoxes(.x, "split")))))
ui2 <- dashboardPage(dashboardHeader(), dashboardSidebar(),
dashboardBody(map(widths, ~ fluidRow(makeBoxes(.x, "col")))))
ui3 <- dashboardPage(dashboardHeader(), dashboardSidebar(),
dashboardBody(map(widths, ~ fluidRow(makeBoxes(.x, "css")))))
shinyApp(ui1, server)
shinyApp(ui2, server)
shinyApp(ui3, server)
I hope this could can be useful. I change width = 11 to 12 and it seems good to me.
Is that what you want ?
library(shiny)
library(purrr)
library(shinydashboard)
widths <- c(1, 2,3, 4, 6, 12)
makeBoxes <- function(width, method = c("split", "col", "css")) {
method <- match.arg(method)
split <- function(width, count) {
splitLayout(selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS,
width = "100%"),
actionButton(paste("ab", width, count, sep = "_"), icon("trash")),
cellWidths = c("87.5%", "12.5%"),
cellArgs = list(style = "vertical-align: top"))
}
col <- function(width, count) {
fluidRow(column(width = 12, # width = 11 -> 12
selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS,
width = "100%")),
column(width = 1,
actionButton(paste("ab", width, count, sep = "_"), icon("trash"))))
}
css <- function(width, count) {
fluidRow(div(selectInput(paste("sel", width, count, sep = "_"), NULL, LETTERS),
style = "display: inline-block; vertical-align: top"),
actionButton(paste("ab", width, count, sep = "_"), icon("trash")))
}
wrap <- function(method, ...)
switch(method, split = split(...), col = col(...), css = css(...))
map(seq(1, 12 / width, 1), function(count)
box(solidHeader = TRUE, title = "Box", status = "info", width = width,
footer = wrap(method, width, count)))
}
server <- function(input, output) {
}
ui2 <- dashboardPage(dashboardHeader(), dashboardSidebar(),
dashboardBody(map(widths, ~ fluidRow(makeBoxes(.x, "col")))))
shinyApp(ui2, server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With