I'm looking for a simple way to select data organised by row with some attributes (namely, year of collection of these data) by column. The columns would be '2016', '2017', '2018' and on each row below each of these columns there should be a checkbox indicating whether the data on this row and for this year should be selected. After this selection has been made, some action (e.g. export) could be performed through a button on this selection. So, nothing exceptional. As there are approx. 1 000 rows in total I would like to speed up a bit the selection proces by allowing the user to select or unselect a whole column (i.e. a whole year).
If possible I would like to do that with DT
. I saw already some related threads, here and there, for instance, but nothing "systematic" (i.e. put select/unselect all checkboxes on top of a subset of columns) as I need here.
Do you know a quick and simple way to do that with DT
?
An alternative would be with rhandsontable
but I have the feeling it's somehow like using a hammer to kill a fly...
[EDIT]: Added reprex below
Inspired from https://github.com/rstudio/DT/issues/93#issuecomment-111001538
library(shiny)
library(DT)
# create a character vector of shiny inputs
shinyInput <- function(FUN, len, id, ...)
{
inputs <- character(len)
for (i in seq_len(len))
{
inputs[i] <- as.character(FUN(paste0(id, i), label = NULL, ...))
}
inputs
}
# obtain the values of inputs
shinyValue <- function(id, len)
{
unlist(lapply(seq_len(len), function(i)
{
value <- input[[paste0(id, i)]]
if (is.null(value)) NA else value
}))
}
Years <- paste0("Year_", 2016:2020)
MyDataFrame <- data.frame(matrix(nrow = 1000, ncol = 1 + length(Years)), stringsAsFactors = FALSE)
colnames(MyDataFrame) <- c("Group", Years)
MyDataFrame[names(MyDataFrame) == "Group"] <- paste0("Group_", 1:1000)
#MyDataFrame[names(MyDataFrame) %in% Years] <- TRUE
MyDataFrame[names(MyDataFrame) %in% Years] <- lapply(X = Years, FUN = function(x){shinyInput(checkboxInput, 1000, paste0('v_', x, '_'), value = TRUE)})
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h4("Filter"),
width = 2
),
mainPanel(
DT::dataTableOutput("MyTable"),
width = 10
)
)
)
server <- function(input, output, session) {
output$MyTable = DT::renderDataTable(MyDataFrame, server = FALSE, escape = FALSE, selection = 'none', options = list(
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
}
shinyApp(ui = ui, server = server, enableBookmarking = "server")
I made progress towards what I am ultimately looking for but I still have an issue: in the reprex below, only the check boxes on the first page are activated or deactivated. Would someone know how to extend the (un)select all effect to all pages, i.e. to the whole table?
library(shiny)
#library(shinyjs)
library(DT)
Generate_shinyInputs <- function(FUN, Range, id, Label, ...)
{
vapply(Range, function(i){as.character(FUN(paste0(id, i), label = if(!is.null(Label)) i else NULL, width = "150px", ...))}, character(1))
}
Years <- 2016:2020
Years_Augmented <- c(Years, "All_Years")
nRows <- 400
MyDataFrame <- data.frame(matrix(nrow = nRows, ncol = 2 + length(Years_Augmented)), stringsAsFactors = FALSE)
colnames(MyDataFrame) <- c("Group", "Country", Years_Augmented)
MyDataFrame[names(MyDataFrame) == "Group"] <- paste0("Group_", 1:nRows)
MyDataFrame[names(MyDataFrame) == "Country"] <- rep(c("AT", "BE", "BG", "CY", "DE", "ES", "FI", "GR", "HU", "IE", "IT"), length.out = nRows)
MyDataFrame[names(MyDataFrame) %in% Years_Augmented] <- lapply(X = Years_Augmented, FUN = function(x){Generate_shinyInputs(checkboxInput, 1:nRows, paste0("CheckBox_", x, "_"), NULL, value = TRUE)})
colnames(MyDataFrame)[names(MyDataFrame) %in% Years_Augmented] <- Generate_shinyInputs(checkboxInput, Years_Augmented, "CheckBox_", TRUE, value = TRUE)
ui <- fluidPage(
mainPanel(
DT::dataTableOutput("MyTable"),
width = 10
)
)
server <- function(input, output, session) {
# Generate the observe events for the columns check boxes (i.e. on the top row) - Total number of check boxes to be observed = number of years + 1 ('All_Years')
Generate_observeEvent_Columns <- function(Year)
{
observeEvent(input[[paste0("CheckBox_", Year)]],
{
CheckBox.Value <- input[[paste0("CheckBox_", Year)]]
if(Year == "All_Years") # Each and every row of each and every column Years_Augmented
{
lapply(X = Years, FUN = function(y){lapply(X = 1:nRows, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", y, "_", x), value = CheckBox.Value)})})
lapply(X = Years, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", x), value = CheckBox.Value)})
}
# Only each and every row of the column 'Year'
lapply(X = 1:nRows, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", Year, "_", x), value = CheckBox.Value)})
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
# Generate the observe events for each row of the column 'All_Years' check boxes - Total number of check boxes to be observed = number of rows (groups)
Generate_observeEvent_Rows <- function(Row)
{
observeEvent(input[[paste0("CheckBox_All_Years_", Row)]],
{
CheckBox.Value <- input[[paste0("CheckBox_All_Years_", Row)]]
print(Row)
lapply(X = Years, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", x, "_", Row), value = CheckBox.Value)})
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
lapply(X = Years_Augmented, FUN = function(x){Generate_observeEvent_Columns(x)})
lapply(X = 1:nRows, FUN = function(x){Generate_observeEvent_Rows(x)})
# filter = 'top',
#output$MyTable = DT::renderDataTable(MyDataFrame, rownames = FALSE, server = FALSE, escape = FALSE, selection = 'none')
output$MyTable = DT::renderDataTable(MyDataFrame, rownames = FALSE, server = FALSE, escape = FALSE, selection = 'none', options = list(
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
}
shinyApp(ui = ui, server = server, enableBookmarking = "server")
[EDIT]:
I'm still working on this problem. I recently split it into simpler problems and by doing so I found a new issue (described after the reproducible example). I am now dynamically printing the values of the relevant inputs to better understand how everything works. The focus is here on the function Generate_observeEvent_Rows
.
Below is a reproducible example:
library(shiny)
#library(shinyjs)
library(DT)
Generate_shinyInputs <- function(FUN, Range, id, Label, ...)
{
vapply(Range, function(i){as.character(FUN(paste0(id, i), label = if(!is.null(Label)) i else NULL, width = "150px", ...))}, character(1))
}
Years <- 2016:2020
Years_Augmented <- c(Years, "All_Years")
nRows <- 40
# 2 + length(Years_Augmented): the first 2 columns are 'Group' and 'Country'
# The next columns are, at first, numbers (the reporting years), except for the last one, 'All_Years'
MyDataFrame <- data.frame(matrix(nrow = nRows, ncol = 2 + length(Years_Augmented)), stringsAsFactors = FALSE)
colnames(MyDataFrame) <- c("Group", "Country", Years_Augmented)
MyDataFrame[names(MyDataFrame) == "Group"] <- paste0("Group_", 1:nRows)
MyDataFrame[names(MyDataFrame) == "Country"] <- rep(c("AT", "BE", "BG", "CY", "DE", "ES", "FI", "GR", "HU", "IE", "IT"), length.out = nRows)
# The cells of the data.frame 'MyDataFrame' in the columns 'Years_Augmented' are checkboxInputs. They are named 'CheckBox_2016_1' where '2016' is the year from 'Years_Augmented' and '1' is the row ID.
MyDataFrame[names(MyDataFrame) %in% Years_Augmented] <- lapply(X = Years_Augmented, FUN = function(x){Generate_shinyInputs(checkboxInput, 1:nRows, paste0("CheckBox_", x, "_"), NULL, value = TRUE)})
# The very names of the last columns ('Years_Augmented') of the data.frame 'MyDataFrame' are thereafter transformed into checkboxInputs. They are named 'CheckBox_2016' where '2016' is the year of the original version of 'Years_Augmented'. The last column then generates 'CheckBox_All_Years'.
colnames(MyDataFrame)[names(MyDataFrame) %in% Years_Augmented] <- Generate_shinyInputs(checkboxInput, Years_Augmented, "CheckBox_", TRUE, value = TRUE)
ui <- fluidPage(
mainPanel(
DT::dataTableOutput("MyTable"),
width = 10
)
)
server <- function(input, output, session) {
# Generate the observe events for the columns check boxes (i.e. on the top row) - Total number of check boxes to be observed = number of years + 1 ('All_Years')
Generate_observeEvent_Columns <- function(Year)
{
observeEvent(input[[paste0("CheckBox_", Year)]],
{
CheckBox.Value <- input[[paste0("CheckBox_", Year)]]
print(paste0("Value of the observed variable '", paste0("CheckBox_", Year), "' = ", CheckBox.Value))
if(Year == "All_Years") # Each and every row of each and every column Years_Augmented
{
lapply(X = Years, FUN = function(y){lapply(X = 1:nRows, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", y, "_", x), value = CheckBox.Value); print(paste0("After update: ", input[[paste0("CheckBox_", y, "_", x)]]))})})
lapply(X = Years, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", x), value = CheckBox.Value); print(paste0("After update: ", input[[paste0("CheckBox_", x)]]))})
}
else # Only one single year was (de)selected (checked/unchecked)
{
lapply(X = 1:nRows, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", Year, "_", x), value = CheckBox.Value); print(paste0("After update: ", input[[paste0("CheckBox_", Year, "_", x)]]))})
}
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
# Generate the observe events for each row of the column 'All_Years' check boxes (not the top row but the rows below) - Total number of check boxes to be observed = number of rows (groups)
Generate_observeEvent_Rows <- function(Row)
{
observeEvent(input[[paste0("CheckBox_All_Years_", Row)]],
{
CheckBox.Value <- input[[paste0("CheckBox_All_Years_", Row)]]
#print(Row)
print(paste0("Value of the observed variable '", paste0("CheckBox_All_Years_", Row), "' = ", CheckBox.Value))
lapply(X = Years, FUN = function(x){print(paste0("Before update of '", paste0("CheckBox_", x, "_", Row), "': ", input[[paste0("CheckBox_", x, "_", Row)]]))})
lapply(X = Years, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", x, "_", Row), value = CheckBox.Value)})
lapply(X = Years, FUN = function(x){print(paste0("After update of '", paste0("CheckBox_", x, "_", Row), "': ", input[[paste0("CheckBox_", x, "_", Row)]]))})
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
#lapply(X = Years_Augmented, FUN = function(x){Generate_observeEvent_Columns(x)})
lapply(X = 1:nRows, FUN = function(x){Generate_observeEvent_Rows(x)})
# filter = 'top',
#output$MyTable = DT::renderDataTable(MyDataFrame, rownames = FALSE, server = FALSE, escape = FALSE, selection = 'none')
#'MyDataFrame' should be updated every time a check box is clicked!
output$MyTable <- DT::renderDataTable(MyDataFrame, rownames = FALSE, server = FALSE, escape = FALSE, selection = 'none', options = list(
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node());}'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node());}')
)
)
#proxy <- DT::dataTableProxy("MyTable")
}
shinyApp(ui = ui, server = server, enableBookmarking = "server")
What I don't understand is that when I click on any of the 'All_Years' column checkbox on one arbitrary row (except of course on the top row, the header), the behaviour of the checkboxes on the same row from 2016 to 2020 is in line with what is expected (i.e. when 'All_Years' on the same row is checked, they become checked, when 'All_Years' on the same row is unchecked, they become unchecked) but their value is not correctly updated: they are always "lagging one step behind".
Do you know why?
Besides, interestingly, we see that only the first 10 rows (the visible part of the table, the current page) of the inputs values are initially displayed in the console (with print
). But that's the next problem to be tackled.
As I wrote last week - but the review decided in the meantime to delete the related message, that would be nice to reinstate it so that the logic flow remains - the code snippet I posted almost 3 years ago no longer works with the latest available versions to date of shiny
(1.10.0) and DT
(0.33), and also, incidentally, data.table
(1.17.0).
I identified the cause and it was simply my mistake. In the function Generate_DataFrame4ShinyDisplay
, this line was faulty (but apparently not with the shiny
version from 3 years ago!):
colnames(DataFrame4ShinyDisplay)[which(names(InputDataFrame) %in% Vector_Columns)] <<- Generate_shinyInputs(checkboxInput, Vector_Columns, "CheckBox_", TRUE, Value = unlist(unname(InputDataFrame[names(InputDataFrame) %in% Vector_Columns][1,])))
Because it basically attempts to modify a checkbox that is already interactively modified by the user, and thus by shiny/the interface, so actually it's not needed in the first place to programmatically modify it.
While I was at it, I noticed the update part of the whole input table was quite inefficiently coded (which translated in relatively slow updates of checkboxes). So I improved that part, esp. by adding the function Toggle_Table4ShinyDisplay
and the results are now much better, both from a logic and user's experience perspectives.
For the sake of completeness I post below the whole updated snippet:
library(shiny)
library(shinyjs)
library(DT)
library(data.table)
Generate_shinyInputs <- function(FUN, Range, id, Label, Value)
{
# I would say the 'as.character' below is the issue, if I understood the Github issue correctly (link after this code block)
vapply(Range, function(i){as.character(FUN(inputId = paste0(id, i), label = if(!is.null(Label)) i else NULL, value = ifelse(is.na(Value[which(Range == i)]), FALSE, Value[which(Range == i)]), width = "150px"))}, character(1))
}
Years <- 2016:2020
Years_Augmented <- c(Years, "All_Years")
nRows <- 200
# ncol of 'Table4ShinySelection' = 2 + length(Years_Augmented): the first 2 columns are 'Group' and 'Country'
# The next columns are, at first, figures/numbers (the reporting years), except for the last one, 'All_Years'
# The very first line/row is for the header of 'Table4ShinyDisplay'
# The subsequent lines/rows (from 2 onwards) are for the subsequent lines/rows of 'Table4ShinyDisplay'
# Actually, it is not necessary to have the first row (header of 'Table4ShinyDisplay') and the last column ('All_Years') in 'Table4ShinySelection' as they drive the other cells; these other cells are the real target.
Table4ShinySelection <- as.data.table(data.frame(matrix(nrow = 1 + nRows, ncol = 2 + length(Years_Augmented)), stringsAsFactors = FALSE))
colnames(Table4ShinySelection) <- c("Group", "Country", Years_Augmented)
Table4ShinySelection[, c("Group") := c("Group_Header", paste0("Group_", 1:nRows))]
Table4ShinySelection[, c("Country") := c("Country_Header", rep(c("AT", "BE", "BG", "CY", "DE", "ES", "FI", "GR", "HU", "IE", "IT"), length.out = nRows))]
# Within the columns 'Years_Augmented', the cells of the table:
# - 'Table4ShinyDisplay' are checkboxInputs. They are named 'CheckBox_2016_1' where '2016' is the year from 'Years_Augmented' and '1' is the row ID.
# - 'Table4ShinySelection' are booleans (TRUE/FALSE) storing the results of the associated checkboxes. All checkboxes are initialised as checked (TRUE).
Table4ShinySelection[, c(Years_Augmented) := TRUE]
Table4ShinySelection[2, c(3, 5) := NA]
Table4ShinySelection[3, c(4, 6) := NA]
# First line/row of 'Table4ShinySelection' is the header of 'Table4ShinyDisplay'
Table4ShinyDisplay <- Table4ShinySelection[-1,]
Table4ShinyDisplay[, c("Group", "Country") := lapply(.SD, as.factor), .SDcols = c("Group", "Country")]
setDF(Table4ShinyDisplay)
Generate_Table4ShinyDisplay <- function(InputTable, Vector_Columns, Vector_Rows)
{
# checkboxInputs are named 'CheckBox_2016_1' where '2016' is the year from 'Years_Augmented' and '1' is the row ID.
Vector_Columns_Indices <- which(colnames(InputTable) %in% Vector_Columns)
Table4ShinyDisplay[Vector_Rows, Vector_Columns_Indices] <<- lapply(X = Vector_Columns, FUN = function(x){Generate_shinyInputs(checkboxInput, Vector_Rows, paste0("CheckBox_", x, "_"), NULL, Value = unname(unlist(InputTable[1 + Vector_Rows, as.character(x), with = FALSE])))})
# The very names of the last columns ('Years_Augmented') of 'Table4ShinyDisplay' are thereafter transformed into checkboxInputs.
# They are named 'CheckBox_2016' where '2016' is the year of 'Years_Augmented'. The last column then generates 'CheckBox_All_Years'.
colnames(Table4ShinyDisplay)[Vector_Columns_Indices] <<- Generate_shinyInputs(checkboxInput, Vector_Columns, "CheckBox_", TRUE, Value = unlist(unname(InputTable[1, Vector_Columns, with = FALSE])))
Table4ShinyDisplay
}
Toggle_Table4ShinyDisplay <- function(Columns_InputTable, Names_Columns, Vector_Rows, Ticked)
{
Names_Columns_Indices <- which(Columns_InputTable %in% Names_Columns)
for(col in Names_Columns_Indices)
{
Table4ShinyDisplay[Vector_Rows, col] <<- sub('class="shiny-input-checkbox" checked="checked"', 'class="shiny-input-checkbox"', Table4ShinyDisplay[Vector_Rows, col])
if(Ticked) Table4ShinyDisplay[Vector_Rows, col] <<- sub('class="shiny-input-checkbox"', 'class="shiny-input-checkbox" checked="checked"', Table4ShinyDisplay[Vector_Rows, col])
#else Table4ShinyDisplay[Vector_Rows, col] <<- sub('class="shiny-input-checkbox" checked="checked"', 'class="shiny-input-checkbox"', Table4ShinyDisplay[Vector_Rows, col])
}
Table4ShinyDisplay
}
Generate_Table4ShinyDisplay(Table4ShinySelection, Years_Augmented, 1:nRows)
Cols_Table4ShinySelection <- colnames(Table4ShinySelection)
ui <- fluidPage(
useShinyjs(),
mainPanel(
dataTableOutput("MyTable"),
actionButton(inputId = "Button_Export_Selection", label = "Export selection"),
width = 10
)
)
server <- function(input, output, session) {
# Refresh/Update all (visible) individual (i.e. not the ones located in the header or on the most right-hand side column) CheckboxInputs so that disabled ones are shown disabled after some events
Refresh_All_CheckboxInputs <- function()
{
lapply(X = 1:nRows, FUN = function(Row){
NAColumns <- colnames(Table4ShinySelection[, c(Years_Augmented), with = FALSE])[is.na(Table4ShinySelection[Row + 1, c(Years_Augmented), with = FALSE])]
lapply(X = NAColumns, FUN = function(Col){updateCheckboxInput(session, paste0("CheckBox_", Col, "_", Row), value = TRUE)})
})
}
# Generate the observe events for the columns check boxes (i.e. on the top row) - Total number of check boxes to be observed = number of years + 1 ('All_Years')
Generate_observeEvent_Columns <- function(Year)
{
observeEvent(input[[paste0("CheckBox_", Year)]],
{
CheckBox.Value <- input[[paste0("CheckBox_", Year)]]
# Indices of rows on all pages (after the table is filtered by the search strings)
FilteredRows <- input[["MyTable_rows_all"]]
Vector_Rows <- intersect(FilteredRows, 1:nRows)
if(Year == "All_Years") # Each and every row of each and every column Years_Augmented
{
if(CheckBox.Value != Table4ShinySelection[1, "All_Years"])
{
lapply(X = Years_Augmented, FUN = function(Year){
NotNARows <- intersect(which(Table4ShinySelection[, !is.na(get(Year))])[-1], Vector_Rows + 1)
Table4ShinySelection[c(1, NotNARows), (Year) := list(CheckBox.Value)]
#replaceData(MyTable_proxy, Generate_Table4ShinyDisplay(Table4ShinySelection, Year, NotNARows - 1), resetPaging = FALSE, rownames = FALSE)
replaceData(MyTable_proxy, Toggle_Table4ShinyDisplay(Cols_Table4ShinySelection, Year, NotNARows - 1, CheckBox.Value), resetPaging = FALSE, rownames = FALSE)
})
lapply(X = Years, FUN = function(x){updateCheckboxInput(session, paste0("CheckBox_", x), value = CheckBox.Value)})
Refresh_All_CheckboxInputs()
}
}
else # Only one single year was (de)selected (checked/unchecked)
{
if(CheckBox.Value != Table4ShinySelection[1, get(as.character(Year))])
{
NotNARows <- intersect(which(Table4ShinySelection[, !is.na(get(as.character(Year)))])[-1], Vector_Rows + 1)
Table4ShinySelection[c(1, NotNARows), (as.character(Year)) := list(CheckBox.Value)]
#replaceData(MyTable_proxy, Generate_Table4ShinyDisplay(Table4ShinySelection, as.character(Year), NotNARows - 1), resetPaging = FALSE, rownames = FALSE)
replaceData(MyTable_proxy, Toggle_Table4ShinyDisplay(Cols_Table4ShinySelection, Year, NotNARows - 1, CheckBox.Value), resetPaging = FALSE, rownames = FALSE)
Refresh_All_CheckboxInputs()
}
}
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
# Generate the observe events for each row of the column 'All_Years' check boxes (not the top row but the rows below) - Total number of check boxes to be observed = number of rows (groups)
Generate_observeEvent_Rows <- function(Row)
{
observeEvent(input[[paste0("CheckBox_All_Years_", Row)]],
{
CheckBox.Value <- input[[paste0("CheckBox_All_Years_", Row)]]
if(CheckBox.Value != Table4ShinySelection[Row + 1, "All_Years"])
{
NotNAColumns <- colnames(Table4ShinySelection[, c(Years_Augmented), with = FALSE])[!is.na(Table4ShinySelection[Row + 1, c(Years_Augmented), with = FALSE])]
Table4ShinySelection[Row + 1, (NotNAColumns) := list(CheckBox.Value)]
#replaceData(MyTable_proxy, Generate_Table4ShinyDisplay(Table4ShinySelection, Years_Augmented, Row), resetPaging = FALSE, rownames = FALSE)
replaceData(MyTable_proxy, Toggle_Table4ShinyDisplay(Cols_Table4ShinySelection, NotNAColumns, Row, CheckBox.Value), resetPaging = FALSE, rownames = FALSE)
Refresh_All_CheckboxInputs()
}
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
#Generate the observe events for all the other checkboxes ("CheckBox_", x, "_", Row) because the selection of these (individual and without side effects on other checkboxes) checkboxes is not saved when e.g. a filter is applied
# Actually adapt 'Generate_observeEvent_Rows' with 2 arguments: c(Year, Row). Not necessarily...
Generate_observeEvent_StandaloneCells <- function(Year, Row)
{
observeEvent(input[[paste0("CheckBox_", Year, "_", Row)]],
{
CheckBox.Value <- input[[paste0("CheckBox_", Year, "_", Row)]]
if(is.na(Table4ShinySelection[Row + 1, get(as.character(Year))]))
{
shinyjs::disable(paste0("CheckBox_", Year, "_", Row))
}
else if(CheckBox.Value != Table4ShinySelection[Row + 1, get(as.character(Year))])
{
Table4ShinySelection[Row + 1, (as.character(Year)) := list(CheckBox.Value)]
#replaceData(MyTable_proxy, Generate_Table4ShinyDisplay(Table4ShinySelection, as.character(Year), Row), resetPaging = FALSE, rownames = FALSE)
replaceData(MyTable_proxy, Toggle_Table4ShinyDisplay(Cols_Table4ShinySelection, as.character(Year), Row, CheckBox.Value), resetPaging = FALSE, rownames = FALSE)
Refresh_All_CheckboxInputs()
}
})#, ignoreNULL = TRUE, ignoreInit = TRUE)
}
lapply(X = Years_Augmented, FUN = function(x){Generate_observeEvent_Columns(x)})
lapply(X = 1:nRows, FUN = function(x){Generate_observeEvent_Rows(x)})
lapply(X = Years, FUN = function(Year){lapply(X = 1:nRows, FUN = function(Row){Generate_observeEvent_StandaloneCells(Year, Row)})})
observeEvent(input[["Button_Export_Selection"]],
{
#That's the easy part
})
output$MyTable <- renderDataTable({
#datatable(Generate_Table4ShinyDisplay(Table4ShinySelection, Years_Augmented, 1:nRows), rownames = FALSE, escape = FALSE, filter = 'top', selection = 'none', options = list(
datatable(Table4ShinyDisplay, rownames = FALSE, escape = FALSE, filter = 'top', selection = 'none', options = list(
dom = 'tp',
ordering = F,
#searching = T,
autoWidth = TRUE,
columnDefs = list(list(targets = which(Cols_Table4ShinySelection %in% Years_Augmented) - 1, searchable = FALSE)),
#pageLength = 10,
preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
}, server = TRUE)
MyTable_proxy <- dataTableProxy("MyTable")
}
shinyApp(ui = ui, server = server)#, enableBookmarking = "server")