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

jsTree not updating when using uiOutput() #15

Open
Jeff-Thompson12 opened this issue Jul 19, 2023 · 9 comments
Open

jsTree not updating when using uiOutput() #15

Jeff-Thompson12 opened this issue Jul 19, 2023 · 9 comments

Comments

@Jeff-Thompson12
Copy link

Here is a minimal example of the behavior. If the jstree output is created using renderUI() in the server, the updating of the tree does not work as expected. (Sidenote: I do not know why the second Root folder is not showing in my example either.)

library(shiny)
library(jsTreeR)

nodes1 <- list(
  list(
    text = "Root1A",
    children = list(
      list(text = "Child1A1")
    )
  ),
  list(
    text = "Root1B",
    children = list(
      list(text = "Child1B1"),
      list(text = "Child1B2")
    )
  )
)

nodes2 <- list(
  list(
    text = "Root2A",
    children = list(
      list(text = "Child2A1"),
      list(text = "Child2A2")
    )
  ),
  list(
    text = "Root2B",
    children = list(
      list(text = "Child2B1")
    )
  )
)

ui <- fluidPage(
  selectInput("node_select", "Select Node List", list("Node 1" = "n1", "Node 2" = "n2")),
  jstreeOutput("dirtree1"),
  uiOutput("dirtree2_ui")
)

server <- function(input, output, session) {
  nodes <- reactiveVal(list())
  
  observeEvent(input$node_select, nodes(ifelse(input$node_select == "n1", nodes1, nodes2)))
  
  output$dirtree2_ui <- renderUI({
    tagList(
      h2(paste("You have selected", input$node_select)),
      jstreeOutput("dirtree2")
    )
  })
  
  output$dirtree1 <- renderJstree(jstree(isolate(nodes())))
  output$dirtree2 <- renderJstree(jstree(isolate(nodes())))
  
  observeEvent(nodes(), {
    jsTreeR::jstreeUpdate(session, "dirtree1", nodes())
    jsTreeR::jstreeUpdate(session, "dirtree2", nodes())
  }, ignoreInit = TRUE)
}

shinyApp(ui, server)

BDDC2F2F-CD86-4127-8011-5A9B683DC332

@stla
Copy link
Owner

stla commented Jul 19, 2023

Don't use ifelse for lists. Do:

  observeEvent(
    input$node_select, 
    nodes(if(input$node_select == "n1") nodes1 else nodes2)
  )

and the second child will appear as expected.

I'm working on the other issue.

@stla
Copy link
Owner

stla commented Jul 19, 2023

Not sure why but it works if you comment a line:

  output$dirtree2_ui <- renderUI({
    tagList(
      #h2(paste("You have selected", input$node_select)),
      jstreeOutput("dirtree2")
    )
  })

@Jeff-Thompson12
Copy link
Author

If you comment that line it won't re-render when input$node_select is changed. If you insert a browser(), you will see it doesn't trigger if you comment out that line when changing the input.

@stla
Copy link
Owner

stla commented Jul 19, 2023

No, it works, because there is jstreeUpdate. I tested and it works.

@Jeff-Thompson12
Copy link
Author

Try this

output$dirtree2_ui <- renderUI({
  input$node_select
  tagList(
    jstreeOutput("dirtree2")
  )
})

It removes the h2() element but still triggers renderUI() whenever input$node_select is changed. This causes it to break.

@stla
Copy link
Owner

stla commented Jul 19, 2023

But don't do this, this is the cause of the problem.

@stla
Copy link
Owner

stla commented Jul 19, 2023

When input$node_select changes, then nodes changes, and the observer is triggered, which triggers the jsTreeUpdate.

@Jeff-Thompson12
Copy link
Author

Maybe this example using {shinyTree} will highlight the problem. I would not expect different behavior if using renderUI(). My point is that this situation is producing unexpected behavior.

library(shiny)
library(jsTreeR)
library(shinyTree)

nodes1 <- list(
  list(
    text = "Root1A",
    children = list(
      list(text = "Child1A1")
    )
  ),
  list(
    text = "Root1B",
    children = list(
      list(text = "Child1B1"),
      list(text = "Child1B2")
    )
  )
)

nodes2 <- list(
  list(
    text = "Root2A",
    children = list(
      list(text = "Child2A1"),
      list(text = "Child2A2")
    )
  ),
  list(
    text = "Root2B",
    children = list(
      list(text = "Child2B1")
    )
  )
)

nodes3 <- list(
  Root1A = list(Child1A1 = ""),
  Root1B = list(Child1B1 = "", Child1B2 = "")
)

nodes4 <- list(
  Root2A = list(Child2A1 = "", Child2A2 = ""),
  Root2B = list(Child2B1 = "")
)

ui <- fluidPage(
  selectInput("node_select", "Select Node List", list("Node 1" = "n1", "Node 2" = "n2")),
  column(
    6,
    jstreeOutput("dirtree1"),
    br(),
    uiOutput("dirtree2_ui")
  ),
  column(
    6,
    shinyTree("dirtree3"),
    br(),
    uiOutput("dirtree4_ui")
  )
)

server <- function(input, output, session) {
  nodes <- reactiveVal(list())
  shinyTree_nodes <- reactiveVal(list())
  
  observeEvent(input$node_select, {
    nodes(if (input$node_select == "n1") nodes1 else nodes2)
    shinyTree_nodes(if (input$node_select == "n1") nodes3 else nodes4)
    })
  
  output$dirtree2_ui <- renderUI({
    input$node_select
    tagList(
      jstreeOutput("dirtree2")
    )
  })
  output$dirtree4_ui <- renderUI({
    input$node_select
    tagList(
      shinyTree("dirtree4")
    )
  })
  
  output$dirtree1 <- renderJstree(jstree(isolate(nodes())))
  output$dirtree2 <- renderJstree(jstree(isolate(nodes())))
  output$dirtree3 <- renderTree(isolate(shinyTree_nodes()))
  output$dirtree4 <- renderTree(isolate(shinyTree_nodes()))
  
  observeEvent(nodes(), {
    jstreeUpdate(session, "dirtree1", nodes())
    jstreeUpdate(session, "dirtree2", nodes())
    updateTree(session, "dirtree3", shinyTree_nodes())
    updateTree(session, "dirtree4", shinyTree_nodes())
  }, ignoreInit = TRUE)
}

shinyApp(ui, server)

@stla
Copy link
Owner

stla commented Jul 19, 2023

I agree it's strange but that's the way it works. My code for the updating is the same as the one of shinyTree.

Another solution is to remove isolate from isolate(nodes).

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

2 participants