Home > Software design >  Why does the table embedded in a separate tab panel from the action buttons that modify not correctl
Why does the table embedded in a separate tab panel from the action buttons that modify not correctl

Time:12-18

When running the code posted at the bottom, the object "hottable" rendered in the "Slave table" tab does not correctly render when outputOptions() is activated at the bottom of the server() section of the code, as illustrated in the image below. Comment out outputOptions() and "hottable" correctly renders. But the use of outputOptions() is critical in this code in order to make "hottable" completely dependent on the column addition/deletion actions in the "Master table" tab (other reactivity problems arise when not using outputOptions()). For reasons not shown in this minimalist example, the action buttons have to be a in a separate tab panel from "hottable". How can this be fixed so "hottable" correctly renders without having to click on it?

Illustration:

enter image description here

Code:

library(dplyr)
library(rhandsontable)
library(shiny)

myDF <- data.frame('Series 1' = c(20,15), check.names = FALSE)
rownames(myDF) <- c('Boy','Girl') 

ui <- pageWithSidebar(
  headerPanel(""),sidebarPanel(""),
  mainPanel(
    tabsetPanel(
      tabPanel("Master table", hr(),
        actionButton("addSeries", "Add", width = 80),
        fluidRow(
          column(2,actionButton("delSeries","Delete", width = 80)),
          column(3,uiOutput("delSeries1")) 
        ),
      ),
      tabPanel("Slave table", hr(),rHandsontableOutput('hottable'))
    )
  )
)

server <- function(input, output) {
  emptyTbl <- reactiveVal(myDF)
  
  observeEvent(input$hottable, {emptyTbl(hot_to_r(input$hottable))})
  
  output$hottable <- renderRHandsontable({
    rhandsontable(emptyTbl(),rowHeaderWidth = 100, useTypes = TRUE)%>%
      hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE) %>%
      hot_cols(colWidths = 80)
  })
  
  observeEvent(input$addSeries, {
    newCol <- data.frame(c(20,15))
    names(newCol) <- paste("Series", ncol(hot_to_r(input$hottable))   1)
    emptyTbl(cbind(emptyTbl(),newCol))
  })
  
  observeEvent(input$delSeries2, {
    tmp <- emptyTbl()                                       
    if(ncol(tmp) > 1){
      delCol <- input$delSeries2                              
      tmp <- tmp[ , !(names(tmp) %in% delCol), drop = FALSE]  
      newNames <- sprintf("Series %d",seq(1:ncol(tmp)))       
      names(tmp) <- newNames                                  
      emptyTbl(tmp)   
    }
  })
  
  output$delSeries1 <- 
    renderUI(
      selectInput("delSeries2", 
                  label = NULL,
                  choices = colnames(hot_to_r(input$hottable)), 
                  selected = "", width = '100px',
                  multiple = TRUE)
      )
  
  outputOptions(output, 'hottable', suspendWhenHidden = FALSE) 
  
}

shinyApp(ui,server)

CodePudding user response:

I know this bug. Here is the fix:

output$hottable <- renderRHandsontable({
  rhandsontable(emptyTbl(), rowHeaderWidth = 100, useTypes = TRUE)%>%
    hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE) %>%
    hot_cols(colWidths = 80) %>%
    htmlwidgets::onRender(
      "function(el, x){
        var hot = this.hot;
        $('a[data-value=\"Slave table\"').on('click', function(){
          setTimeout(function(){ hot.render(); }, 200);
        }); 
      }"
    )
})

Not sure the 200 milliseconds in setTimeout are necessary.

  • Related