Sunday, August 5, 2018

Place button next to selectInput

Leave a Comment

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 big
  • inline-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) 

1 Answers

Answers 1

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 Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment