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

jsTreeR disables reactive callbacks from bslib nav containers #33

Open
datatenk opened this issue May 7, 2024 · 5 comments
Open

jsTreeR disables reactive callbacks from bslib nav containers #33

datatenk opened this issue May 7, 2024 · 5 comments

Comments

@datatenk
Copy link

datatenk commented May 7, 2024

This problem may be related to issue: #32 (comment)

After switching from shinyTree to jsTreeR, the callbacks from bslib::navset_pill_list appears to be broken when rendered through renderUI. The desirable behavior is that whenever the user activates a certain nav_panel in the navset_pill_list container, the value the nav_panel should be accessible through the input$id_of_navset_pill_list_container. However, when jsTreeR is used with renderUI, the input$id_of_navset_pill_list_container is never updated when the user activates certain panels, and remains at the initialized value of NULL at all times.

2 Reprex's are made with shinyTree and jsTreeR

Firstly, the reprex with shinyTree showing desirable reactive behaviour:

library(shiny)
library(bslib)
library(shinyWidgets)
library(shinyTree)
library(jsTreeR)

# using shinyTree
nodes_shinyTree<-list(foo=list(bar=list()))

shinyTree_ui<-card(
  shinyTree('shinyTree_tree_ui'),
  verbatimTextOutput(outputId='selected_navset_ui'),
  bslib::navset_pill_list(
    id='navset_ui',
    nav_panel(title="A",value="A"),
    nav_panel(title="B",value="B"))
)

ui_shinyTree<-page_navbar(
  title='shinyTree',
  
  nav_panel(
    title='shinyTree',
    card(
      shinyTree('shinyTree_tree'),
      verbatimTextOutput(outputId='selected_navset'),
      bslib::navset_pill_list(
        id='navset',
        nav_panel(title="A",value="A"),
        nav_panel(title="B",value="B"))
    )
  ),

  nav_panel(
    title='shinyTree uiOutput',
    uiOutput('shinyTree_ui')
  )
  
)

server_shinyTree<-function(input,output,session){
  output$shinyTree_tree<-renderTree(nodes_shinyTree)
  output$selected_navset<-renderText(input$navset)

  output$shinyTree_ui<-renderUI(shinyTree_ui)
  output$shinyTree_tree_ui<-renderTree(nodes_shinyTree)
  output$selected_navset_ui<-renderText({
    if(is.null(input$navset_ui)){
      'select from navset'  
    } else {
      input$navset_ui  
    }
  })
  
}

shinyApp(ui_shinyTree,server_shinyTree)

Now the reprex with jsTreeR, where the input$navset_ui fails to update on change:

library(shiny)
library(bslib)
library(shinyWidgets)
library(shinyTree)
library(jsTreeR)

# using jsTreeR
nodes_jsTreeR<-list(list(text='foo',children=list(list(text='bar'))))

jsTreeR_ui<-card(
    jstreeOutput('jstree_tree_ui'),
    verbatimTextOutput(outputId='selected_navset_ui'),
    bslib::navset_pill_list(
      id='navset_ui',
      nav_panel(title="A",value="A"),
      nav_panel(title="B",value="B"))
)


ui_jsTreeR<-page_navbar(
  title='jsTreeR',
  
  nav_panel(
    title='jsTreeR',
    card(
      jstreeOutput('jstree_tree'),
      verbatimTextOutput(outputId='selected_navset'),
      bslib::navset_pill_list(
        id='navset',
        nav_panel(title="A",value="A"),
        nav_panel(title="B",value="B"))
    )
  ),

  nav_panel(
    title='jsTreeR uiOutput',
    uiOutput('jsTreeR_ui')
  )
)

server_jsTreeR<-function(input,output,session){
  output$jstree_tree<-renderJstree(jstree(nodes_jsTreeR))
  output$selected_navset<-renderText(input$navset)
  
  
  output$jsTreeR_ui<-renderUI(jsTreeR_ui)
  output$jstree_tree_ui<-renderJstree(jstree(nodes_jsTreeR))
  output$selected_navset_ui<-renderText({
    if(is.null(input$navset_ui)){
      'select from navset'  # This is always displayed
    } else {
      input$navset_ui  # This is never displayed since input$navset_ui never updates
    }
  })
  
}

shinyApp(ui_jsTreeR,server_jsTreeR)

The reprex's differ only by which wrapper is used to interface with jsTree (shinyTree vs jsTreeR).

@stla
Copy link
Owner

stla commented May 8, 2024

You're definitely a bug finder!

But again, this is not related to the jstree in renderUI: remove jstreeOutput('jstree_tree_ui') and you will see the bug is still there.

@stla
Copy link
Owner

stla commented May 8, 2024

I identified (but not solved) the problem. The li elements of the problematic nav and their a descendant do not have the required classes, nav-item and nav-link respectively. If I manually add these classes, then that works.

@datatenk
Copy link
Author

datatenk commented May 8, 2024

You're definitely a bug finder!

But again, this is not related to the jstree in renderUI: remove jstreeOutput('jstree_tree_ui') and you will see the bug is still there.

Thanks for the response. Can you elaborate on what you mean by removing jstreeOutput('jstree_tree_ui') and the error disappears? A code snippet would be helpful.

I would respectfully disagree with the statement that the problem at hand is not related to jsTreeR, because if I use another wrapper (shinyTree), the expected behavior is restored. It is only when I incorporate jsTreeR, the wrong behavior exists, and no other time. My double-reprex in this post and the other one are intended to demonstrate this point very explicitly in a change-one-variable-at-a-time approach, i.e. change from shinyTree to jsTreeR, results from good to broken.

@stla
Copy link
Owner

stla commented May 8, 2024

Can you elaborate on what you mean by removing jstreeOutput('jstree_tree_ui') and the error disappears?

It does not disappear, on the contrary, it persists!

Simply comment one line:

jsTreeR_ui<-card(
    # jstreeOutput('jstree_tree_ui'),
    verbatimTextOutput(outputId='selected_navset_ui'),
    bslib::navset_pill_list(
      id='navset_ui',
      nav_panel(title="A",value="A"),
      nav_panel(title="B",value="B"))
)

and you will see the problem is still there.

I would respectfully disagree with the statement that the problem at hand is not related to jsTreeR

It is related to jsTreeR, because the bug disappears if you remove the other jstreeOutput. And it is also related to renderUI.

@datatenk
Copy link
Author

datatenk commented May 8, 2024

Thanks for your comment.
In addition to the comment-out jstreeOutput('jstree_tree_ui') from the ui, disabling output$jstree_tree_ui<-renderJstree(jstree(nodes_jsTreeR)) in the server would complete restore the navset's reactive input updates.

Meanwhile, with the only change being the removal of renderJsTree function call from the server, navset_bill_list is still being rendering by renderUI (unchanged), and that appears to be functioning as expected. It is not possible to conclude that there is a problem with renderUI from that observation.

Code snippet:

server_jsTreeR<-function(input,output,session){
  output$jstree_tree<-renderJstree(jstree(nodes_jsTreeR))
  output$selected_navset<-renderText(input$navset)
  
  
  output$jsTreeR_ui<-renderUI(jsTreeR_ui)
  # output$jstree_tree_ui<-renderJstree(jstree(nodes_jsTreeR))   
  output$selected_navset_ui<-renderText({
    if(is.null(input$navset_ui)){
      'select from navset'  # This is always displayed
    } else {
      input$navset_ui  # This is never displayed since input$navset_ui never updates
    }
  }) 
}

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