How to Align a Group of Checkboxgroupinput in R Shiny

How to align a group of checkboxGroupInput in R Shiny

A solution to this problem can be achieved by adjusting the div tags. A small example shiny app for illustration:

library(shiny)

# tweaks, a list object to set up multicols for checkboxGroupInput
tweaks <-
list(tags$head(tags$style(HTML("
.multicol {
height: 150px;
-webkit-column-count: 5; /* Chrome, Safari, Opera */
-moz-column-count: 5; /* Firefox */
column-count: 5;
-moz-column-fill: auto;
-column-fill: auto;
}
"))
))

# values to show, or not show, these will be the 'choices' and 'selected' values
# for the checkboxGroupInput()
all_rows <- 1:25
names(all_rows) <- paste("Row", all_rows)

# data control: the checkboxes will control the data values plotted
controls <-
list(h3("Multicolumn checkboxGroupInput"),
tags$div(align = 'left',
class = 'multicol',
checkboxGroupInput(inputId = 'numSelector',
label = "Select the numbers:",
choices = all_rows,
selected = all_rows,
inline = FALSE)))

# run the app
runApp(list(
ui = fluidPage(tweaks,
fluidRow(column(width = 4, controls),
column(width = 8, plotOutput("plot")))),
server = function(input, output) {
plot_data <- reactive(input$numSelector)

output$plot <- renderPlot(plot(x = plot_data(),
y = plot_data(),
pch = 6,
cex = 2,
xlim = c(1, 25),
ylim = c(1, 25)))
}))

The checkboxGroupInput looks like this:

Sample Image

I cobbled this solution together with help form: CSS-Tricks and This Google Groups post.

Aligning checkbox elements in many coumns in a Shiny app

There is a small margin on the top of the first checkbox. Use the code below to remove it. Note the last line which is the only line that I added.

shinyUI(
navbarPage("navbar",
tabPanel(strong("Buscador"),value="panel2",
tags$head(tags$style(HTML(".multicol{font-size:12px;
height:auto;
-webkit-column-count: 2;
-moz-column-count: 2;
column-count: 2;
}

div.checkbox {margin-top: 0px;}"))),

Align checkBoxGroupInput vertically and horizontally

The following code should do the trick. You needed to apply the CSS columns a div below where you had them and then remove padding from above and below the check boxes, I also changed the column fill to balanced:

library(shiny)
examplesubset<-read.table(text="
elements locations
element_One A,M,P,A,R,T
element_Two A,B,C,M,P,E,I,N,S
element_Three G,M,T,F,S,V,P" , header=TRUE, stringsAsFactors=FALSE)
examplesubset$elements<-as.factor(examplesubset$elements)

ui<-fluidPage(
tags$head(tags$style(HTML("
.multicol .shiny-options-group{
-webkit-column-count: 3; /* Chrome, Safari, Opera */
-moz-column-count: 3; /* Firefox */
column-count: 3;
-moz-column-fill: balanced;
-column-fill: balanced;
}
.checkbox{
margin-top: 0px !important;
-webkit-margin-after: 0px !important;
}
"))),
titlePanel("Panel"),
sidebarLayout(
sidebarPanel(
selectInput("elements", "Select elements:",
choices=examplesubset$elements)
) ,
mainPanel(
fluidRow(
column(3,
uiOutput("checkboxesui")
))))
)

server<-function(input, output,session) {
elementsselected<-reactive({
sp<-examplesubset[examplesubset$elements==input$elements,]
sp<-droplevels(sp)
})
locationsreactive<- reactive({
j<-as.factor(unique(unlist(strsplit(elementsselected()$locations, ",", fixed = TRUE) ) ) )
j<-droplevels(j)
})
output$checkboxesui<-renderUI({
tags$div(align = 'left',
class = 'multicol',
checkboxGroupInput("locationscheckboxes", "locations",
choices=levels(locationsreactive())
, selected=c() )
)
})
}
shinyApp(ui = ui, server = server)

Fixed

The other option is to use CSS flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

This would solve the ordering issues you described, but you would need to dink with the sizes of the shiny-options-group div to get everything to fit the way you want, depending on your content. It is probably easier to just reorder your checkbox options so they display the way you want.

Shiny: validate for a group of checkboxGroupinput

You can use:

need(!is.null(input$marker1) | !is.null(input$marker2) | !is.null(input$marker3), 
'Check at least one color!')

R Shiny display checkboxGroupInput horizontally

You can do like this :

checkboxGroupInput(inputId="test", label="Test", choices=1:4),
tags$style(type="text/css", HTML("#test>*{float: left; margin-right: 15px; height: 20px;} #test {height: 20px;}"))

Or directly edit a css file, see https://groups.google.com/forum/#!topic/shiny-discuss/EMQV8NbA3MI

EDIT

Since shiny 0.10.0, you can use the inline argument for horizontal layout :

library("shiny")
ui <- fluidPage(
checkboxGroupInput(inputId="test", label="Test", choices=1:4, inline = TRUE)
)
server <- function(input, output) {

}
shinyApp(ui = ui, server = server)

Shiny: dynamic checkboxGroupInput

I simplified the code a bit to demonstrate how the group checkboxes could work.

In simplifying, I kept the data as a list from the csv files. Then for computations extracted the second column from all data frames in the list, then used select to show columns based on the checkboxes.

The checkbox items are based on the names of the second columns of the data, with a default of all selected.

Instead of entering the number of files that were read, it is now computed based on the length of the list of data.

Let me know if this is closer to what you need.

library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(data.table)
library(dplyr)
library(xlsx)

sidebar <- dashboardSidebar(
width = 350,
sidebarMenu(
tags$style(HTML(".sidebar-menu li a { color: #f4f8e8; }")),
menuItem("Computations",tabName = "tab1", icon = icon("file-text-o"))
))

body <- dashboardBody(
tags$style(".content-wrapper {background-color: #c3f9fa;}"),
style = "color: black;",
tabItems(
tabItem(
tabName = "tab1",
h2("upload files"),
tags$style(HTML(" .progress-bar { background-color: #1dbcbf; }")),
fileInput("csvs",
label="Upload CSVs here",
multiple = TRUE),
textOutput("numfiles"),
box(title = "tab after computations:",tableOutput("all_cols"),width = 100),
uiOutput("checkboxes")
)))

dbHeader <- dashboardHeader(title = 'Exercise')

ui <- dashboardPage(
skin = "black",
dbHeader,
sidebar,
body
)

server <- function(input, output) {
options(shiny.maxRequestSize=260*1024^2)

db <- reactiveVal(list())

computations <- function(){
req(input$checkboxes)
do.call(cbind, lapply(db(), "[", , 2)) %>%
select_if(names(.) %in% input$checkboxes)
}

observeEvent(input$csvs, {
db(lapply(input$csvs$datapath, fread))
})

output$numfiles <- renderText(paste("Number of files: ", length(db())))

output$checkboxes <- renderUI({
choice_list <- unlist(lapply(db(), function(x) colnames(x)[2]))
checkboxGroupInput("checkboxes", "Columns to keep:", choices = choice_list, selected = choice_list)
})

output$all_cols <- renderTable(computations(), align = 'c', rownames = TRUE, colnames = TRUE, digits = 3)

}

shinyApp(ui = ui, server = server)


Related Topics



Leave a reply



Submit