rshinyshinytree

input$shinyTree does not get updated after new render


In the shiny app below, I have a reset button, which, well, resets the shinyTree. I figured that the corresponding input$tree does not get updated after pressing the reset, i.e. input$tree still reflects the un-reset state. Try the app by moving some nodes and press the reset button and you will see that while the output gets reset the verbatimTextOutput still shows the old version.

Is that behavior intentional? How do I force shinyTree to update the input$tree whenever output$tree is changed? Would #89 solve my issue?

library(shiny)
library(shinyTree)

ui <- fluidPage(actionButton("reset", "reset"),
                shinyTree("tree", dragAndDrop=TRUE, sort = F, wholerow = T, unique = T),
                verbatimTextOutput("str"))



server <- function(input, output, session) {
  output$tree <- renderTree({
    input$reset
    list(
      root3 = "234",
      root1 = list(
        SubListA = list(leaf1 = "", leaf2 = "")
      ),
      root2 = list(
        SubListA = list(leaf1 = "", leaf2 = "")
      )
    )
  })

  output$str <- renderPrint({
    # shinyTrees will also be available as inputs so you can
    # monitor changes that occur to the tree as the user interacts
    # with it.
    str(input$tree)
  })
}

shinyApp(ui, server)

To clarify: I have read R Shiny - Resetting shinyTree node selections before posting this question and though related, it is not solving my problem, because I am not using updateTree in the first place and in my real use case things are way more complicated. Thus, the highlighted solution to use an additional reactiveVal won't work smoothly.

I really need a solution which assures that input$tree is up to date regardless whether the tree was updated through user interaction or through R code itself.

I have only a superficial understanding of shiny input widgets, but I guess that #89 could solve my issue as it will pass a new tree to shiny whenever there is a refresh. I will try this one out.


Solution

  • Please check the following, you can force to reset input$tree via JS:

    library(shiny)
    library(shinyTree)
    library(shinyjs)
    
    ui <- fluidPage(
      useShinyjs(),
      actionButton("reset", "reset"),
                    shinyTree("tree", dragAndDrop=TRUE, sort = F, wholerow = T, unique = T),
                    verbatimTextOutput("str"))
    
    server <- function(input, output, session) {
    
      observeEvent(input$reset, {
        runjs("Shiny.setInputValue('tree', null);")
      })
    
      output$tree <- renderTree({
        input$reset
        list(
          root3 = "234",
          root1 = list(
            SubListA = list(leaf1 = "", leaf2 = "")
          ),
          root2 = list(
            SubListA = list(leaf1 = "", leaf2 = "")
          )
        )
      })
    
      output$str <- renderPrint({
        str(input$tree)
      })
    }
    
    shinyApp(ui, server)