0

The following code was modified from the answer to an earlier post R Shiny, how to make datatable react to checkboxes in datatable. It works fine in its original form. Now I added a "subset data" button so that users can remove the unchecked rows from the display. (I also added a "load data" button because later I would like the data file to be uploaded by users.) Curiously it only works for the first time, then it ceases responding. Could someone please help figuring out the problem?

Here is the code:

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    actionButton("LoadData", label="Load data", class="btn-primary"),
    DT::dataTableOutput('x1'),
    verbatimTextOutput('x2'),
    actionButton("SubsetDT", label="Subset data", class="btn-primary")
  ),
  
  server = function(input, output, session) {
    # create a character vector of shiny inputs
    shinyInput = function(FUN, len, id, value, ...) {
      if (length(value) == 1) value <- rep(value, len)
      inputs = character(len)
      for (i in seq_len(len)) {
        inputs[i] = as.character(FUN(paste0(id, i), label = NULL, value = value[i]))
      }
      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)) TRUE else value
  }))
}

n = 6
df = data.frame(
  cb = shinyInput(checkboxInput, n, 'cb_', value = TRUE, width='1px'),
  month = month.abb[1:n],
  YN = rep(TRUE, n),
  ID = seq_len(n),
  stringsAsFactors = FALSE)

loopData = reactive({
  df$cb <<- shinyInput(checkboxInput, n, 'cb_', value = shinyValue('cb_', n), width='1px')
  df$YN <<- shinyValue('cb_', n)
  df
})

observeEvent(input$LoadData, {
  output$x1 = DT::renderDataTable(
    isolate(loopData()),
    escape = FALSE, selection = 'none',
    options = list(
      dom = 't', paging = FALSE, ordering = FALSE,
      preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
      drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
    ))
})

observeEvent(input$SubsetDT, {
  output$x1 = DT::renderDataTable(
    isolate(subset(loopData(),YN==T)),
    escape = FALSE, selection = 'none',
    options = list(
      dom = 't', paging = FALSE, ordering = FALSE,
      preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
      drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
    ))
})

proxy = dataTableProxy('x1')

observe({
  replaceData(proxy, loopData(), resetPaging = FALSE)
})

output$x2 = renderPrint({
  data.frame(Like = shinyValue('cb_', n))
})
  }
)

Many thanks in advance.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • That is because you are using the same ID in `loopData` that has been used in `df` dataframe creation. All IDs should be unique. – YBS Sep 29 '22 at 13:19
  • Thank you. Is it possible to remove the ones used in the first round? I tried removeUI without success. Or how can I work around the problem? – Terpsiphone Sep 30 '22 at 01:35
  • Try to avoid it in the reactive object. It will only work the first time. – YBS Sep 30 '22 at 01:53
  • I am looking for similar problems. @Terpsiphone does the solutions givens works and if yes, may you give the final answer please ? – VincentP Mar 27 '23 at 07:49

0 Answers0