Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datatable in insertUI rerenders other datatable #369

Closed
carlganz opened this issue Oct 24, 2016 · 3 comments
Closed

datatable in insertUI rerenders other datatable #369

carlganz opened this issue Oct 24, 2016 · 3 comments
Milestone

Comments

@carlganz
Copy link
Contributor

See this SO question: http://stackoverflow.com/questions/40225191/generating-dynamic-number-of-datatables-without-rerendering/

Reproducible example from @warmoverflow

library(shiny)
library(DT)

numUI <- 0

ui <- shinyUI(fluidPage(
  mainPanel(
    sliderInput("number","Number of tables",1,10,1,1),
    tags$div(id="tables")
  )))

server <- shinyServer(function(input, output, session) {

  observe({
    if (input$number > numUI) {
      for (num in (numUI+1):input$number) {
        insertUI("#tables", "beforeEnd", DT::dataTableOutput(paste0("table", num)))
        output[[paste0("table",num)]] <- DT::renderDataTable(head(mtcars), server = FALSE)
      }
    }

    if (input$number < numUI) {
      for (num in (input$number+1):numUI) {
        removeUI(paste0("#table", num))
      }
    }

    numUI <<- input$number
  })

})
# Run the application
shinyApp(ui = ui, server = server)

When you insert a new datatable all of the datatables rerender, so information like selected rows, and the search filters are lost. This seems counter to the whole purpose of insertUI as an alternative to renderUI.

Thanks

@yihui
Copy link
Member

yihui commented Oct 25, 2016

Sorry I don't have time to investigate this issue for now. I wonder if @bborgesr has any ideas here.

@bborgesr
Copy link

bborgesr commented Oct 25, 2016

Thanks for the report. It seems like for insertUI, Shiny will re-render an element whenever it is changed (even if only a child inside of it changes). Interestingly, this does not happen for removeUI. However, this is not intended and should be fixed in Shiny (I've opened an issue there and will close it when the fix is in place, in case you want to follow the progress: rstudio/shiny#1438). Until then, however, here's a fix you can do.

In your case, what is happening is that #tables is always changing whenever you add a new table because your "where" argument for insertUI is "beforeEnd", which means that each new table is a new element of the div #tables. Since #tables is changing each time, everything gets re-rendered... The good news is that we can easily get around this problem by using "beforeBegin" instead of "beforeEnd". From the user perspective, this looks the same (each new table is added after any existing tables). However, your DOM looks different: instead of having a #tables div with one or more tables, you always have a empty #tables div, and above (as siblings), you have one or more tables. If that's okay by you (even though it's a lot less elegant), it would be the best fix until I solve the underlying problem...

library(shiny)
library(DT)

numUI <- 0

ui <- shinyUI(fluidPage(
  mainPanel(
    sliderInput("number","Number of tables",1,10,1,1),
    tags$div(id="tables")
  )))

server <- shinyServer(function(input, output, session) {

  observe({
    if (input$number > numUI) {
      for (num in (numUI+1):input$number) {
        insertUI("#tables", "beforeBegin", DT::dataTableOutput(paste0("table", num)))
        output[[paste0("table",num)]] <- DT::renderDataTable(head(mtcars), server = FALSE)
      }
    }

    if (input$number < numUI) {
      for (num in (input$number+1):numUI) {
        removeUI(paste0("#table", num))
      }
    }

    numUI <<- input$number
  })

})
# Run the application
shinyApp(ui = ui, server = server)

PS: @yihui, you can close the issue here, since it's a Shiny issue, not a DT issue.

@yihui yihui added this to the v0.3 milestone Oct 25, 2016
@yihui
Copy link
Member

yihui commented Oct 25, 2016

Excellent. Thanks a lot, Barbara!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants