Hi,
Welcome to the RStudio community!
Here is another way of doing this. It might be a bit more convoluted, but I think the result is visually pretty
library(shiny)
library(DT)
ui <- fluidPage(
dataTableOutput("myTable")
)
server <- function(input, output, session) {
#The proxy to update the DT
proxy <- dataTableProxy('myTable')
#The initial data for the checkboxes
checkboxes = data.frame(
Name = c(NA, as.character(icon("ok", lib = "glyphicon"))),
Time = c(NA, as.character(icon("ok", lib = "glyphicon"))),
Budget = c(as.character(icon("ok", lib = "glyphicon")), NA),
row.names = paste("Project", 1:2)
)
#The reactive version of the data
tableData = reactiveValues(checkboxes = checkboxes)
#Update the table when clicked
observeEvent(req(input$myTable_cells_selected), {
tableData$checkboxes[input$myTable_cells_selected] =
ifelse(is.na(tableData$checkboxes[input$myTable_cells_selected]),
as.character(icon("ok", lib = "glyphicon")), NA)
#Send proxy (no need to refresh whole table)
replaceData(proxy, tableData$checkboxes)
})
#The "checkbox" table
output$myTable = renderDataTable({
checkboxes
},
#These are options to make the table look like checkboxes
selection = list(mode = "single", target = 'cell'),
options = list(
columnDefs = list(list(className = 'dt-center', targets = "_all")),
dom = "t", ordering = F
),
escape = F)
}
shinyApp(ui, server)
The trick I did was use the datatable package to put icons (checkmarks) into the cells and use the proxy to update the table when a specific cell is clicked. This way there is minimal data transfer. The great thing about this approach is that the data will always be in a nice grid and scale with page (you can change that of course). Also, you are now able to use both rows and column names, which is not possible with the traditional checkboxes.
To get the actual list of "checked boxes", you can simply convert the table to a logical matrix when you need it
!is.na(tableData$checkboxes)
Name Time Budget
Project 1 FALSE FALSE TRUE
Project 2 TRUE TRUE FALSE
Hope this helps,
PJ