how to reset observers

I have this small app.

I am dividing a dataframe in slices, using a previous and next button I am iterating showing the different slices of it in a datatable.

Inside the datatable I have checkboxes, their IDs are reset programmatically as soon as the new slice is requested.

From a tibble with 30 rows:

  • I select the subset of it with a reactive value
  • I define the checkboxes IDs
  • I display the table
  • I observe the inputs with lapply, at the first render they are setup properly, when changing a checkbox it is printed in the console
  • then I press the next button, a new table is rendered, the lapply function run again but this time the observers don't work anymore

the first display works, as soon as it changes I need a way to reset the observers.

sample code:

library("DT")
library("shinyjs")
library("tidyverse")
library("shiny")

ui <- basicPage(
  h2("The mtcars data"),
  useShinyjs(),
  actionButton("prv", "prv", icon("arrow-left")),
  actionButton("nxt", "nxt", icon("arrow-right")),
  DT::dataTableOutput("mytable")
)

server <- function(input, output) {
  
  ###Sample Data
  mtcarsx <- reactive(
    data.frame(mtcars) %>%
      as_tibble() %>%
      mutate( slice=round(runif(row_number(),min=1,max=5))  ) 
  )
  
  ###Slice selector that will be modified with the button
  sliceN <- reactiveVal(1)
  
  ###Manipulating the slice
  thisSlice <- reactive({
    mtcarsx() %>%
      filter(slice==sliceN()) %>%
      mutate(rown=row_number()) %>%
      rowwise() %>% 
      mutate( 
        randmz=runif(row_number(),min=0,max=3),
        newvar=case_when(
          #I have checkboxes defaulted to true, checkboxes defaulted to false, checkboxes defaulted to true that I will disable
          randmz < 1 ~ as.character(checkboxInput(paste0("chk",rown),label="",value=TRUE)),
          randmz < 2 ~ as.character(checkboxInput(paste0("chk",rown),label="",value=FALSE)),        
          TRUE ~ as.character(checkboxInput(paste0("chk",rown),label="",value=TRUE))          
        ),
        mytype=case_when(
          #I have checkboxes defaulted to true, checkboxes defaulted to false, checkboxes defaulted to true that I will disable
          randmz < 1 ~ "MYTRUE",
          randmz < 2 ~ "MYFALSE",        
          TRUE ~ "DISABLED"          
        )
      )
  })
  
  #to disable checkboxes
  observe({
    print(input$chk1)
    n <- nrow(thisSlice())
    lapply(1:n, function(i){if(thisSlice()$mytype[i]=="DISABLED"){  shinyjs::disable(paste0("chk",i)) } })
  })
  
  #to listen to checkboxes
  observeEvent(input,{
    print(input$chk1)
    n <- nrow(thisSlice())
    lapply(
      1:n, 
      function(i){ 
        observeEvent(input[[paste0("chk",i)]],{
          print(paste0("chk",i))
          #print(input[[paste0("chk",i)]])
        })
      })   
  })
  
  
  
  #previous and next buttons
  observeEvent(input$nxt, {
    sliceN(sliceN()+ 1) 
  })
  observeEvent(input$prv, {
    sliceN(sliceN()- 1)
  }) 
  
  #display
  output$mytable = DT::renderDataTable({
    #print(thisSlice())
    DT::datatable(thisSlice(), 
                  escape = FALSE, 
                  selection = 'none', 
                  rownames = TRUE, 
                  extensions = c('FixedColumns'),
                  options = list(searching = FALSE, 
                                 ordering  = FALSE,
                                 autoWidth = TRUE,
                                 scrollX = TRUE,
                                 FixedColumns = list(leftColumns = c(2)),
                                 preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
                                 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
                  ))
  })
  
}

shinyApp(ui, server)

how can I reset the observers when "next" is pressed and after the render of the datatable?

I also tried triggering the event after draw with a javascript callback like this:

  observeEvent(input$mycback,{
    print("received")
    o$destroy
    o
  })

o<-observeEvent(input,{
same as before
})

and in the dt callback

drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); Shiny.setInputValue("mycback","drawn", {priority: "event"})} '),

pasting the disable code inside my callback I've been able to call the disable function after redraw of the table successfully!! big success.

still the observers can listen for changes ONLY at the first draw, I can't explain why.

this is xposted from stackoverflow

Hey, just to say that I'm struggling so much with this and still didn't find a solution.

I have no clue where to look next.

If not a solution, please just provide some hints, I would really appreciate it.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.