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:
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)
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
Converting a Factor to Numeric Without Losing Information R (As.Numeric() Doesn't Seem to Work)
Combination Boxplot and Histogram Using Ggplot2
Saving Plot as PDF and Simultaneously Display It in the Window (X11)
Using R to Analyze Balance Sheets and Income Statements
Fastest Way to Multiply Matrix Columns with Vector Elements in R
Is There a More Efficient Way to Replace Null with Na in a List
How to Create a List of Vectors in Rcpp
How to Remove Duplicated Column Names in R
How to Solve Prcomp.Default(): Cannot Rescale a Constant/Zero Column to Unit Variance
Add Density Lines to Histogram and Cumulative Histogram
Jitter If Multiple Outliers in Ggplot2 Boxplot
How to Check the Existence of a Downloaded File
R Shiny - Disable/Able Shinyui Elements
R: How to Total the Number of Na in Each Col of Data.Frame
How to Remove Multiple Columns in R Dataframe
Embedding an R HTMLwidget into Existing Webpage
Subscripts and Superscripts "-" or "+" with Ggplot2 Axis Labels? (Ionic Chemical Notation)