Open sorhawell opened 5 years ago
I come somewhat closer. I can close menus. In this case if sub-sub branches of branch1 is open. I can close the sub branches by pressing the button. It is ofc not the overall intention to control via a button, but it would be an example of server side control of ShinyTreeMenu
How do I choose if to open or close a menu. How does shinyTreeMenu store the current state of open close?
#new update that do not care if treemenu_open input is reactive or absolute
newupdateShinyTreeMenu <- function(treedata, treemenu_open, level_icons) {
print("evalute reactiveness")
td = if(inherits(treemenu_open,"reactive")) {
print("try reactive")
print(class(treemenu_open))
treemenu_open()
} else{
print("try non-reactive")
print(class(treemenu_open))
treemenu_open
}
shiny::observeEvent(td, {
shinyjs::html(id = paste0("treemenu_open_", td$openid),
html =
ShinyTreeMenu:: ShinyTreeMenuHTML(
treedata = treedata(),
select_id = td$openid,
level_icons = level_icons))
})
}
if (interactive()) {
global_i = 1
shinyApp(
ui = fluidPage(
# ShinyTreeMenu uses shinyjs - so remember to include shinyjs in your UI
shinyjs::useShinyjs(),
actionButton("abot","press me"),
ShinyTreeMenuOutput("treemenu")
),
server = function(input, output, session) {
# Treedata has to be in the form of a reactive expression
treedata <- reactive({
td = ShinyTreeMenu::treetestdata
#print(td)
td
})
##Here is the actual suggestion
observeEvent(input$abot,ignoreInit = TRUE,{
print("sending js script")
#runjs("var today = new Date(); alert(today);")
#shinyjs::runjs("Shiny.setInputValue('treemenu_open', {openid:'1', randomVal:Math.random()});")
newupdateShinyTreeMenu(treedata,treemenu_open = list(openid="1",randomVal=runif(1)),level_icons = "tree")
})
# Use the shiny callModule to render the ShinyTreeMenu
# Note that you should not include () when adding your reactive treedata
shiny::callModule(ShinyTreeMenu::renderShinyTreeMenu,
id = "treemenu",
treedata = treedata,
level_icons = "plus")
#print what open id is before and after update
r_treemenu_open = reactive({
tm_o = input$treemenu_open
global_i <<- global_i + 1
print(global_i)
print(tm_o)
tm_o
})
observe({
cat("tm_o:",unlist(r_treemenu_open())," global_i ",global_i)
})
# Here you will update the ShinyTreeMenu
# As with the render function, you should not include () when adding your reactive treedata
ShinyTreeMenu:: updateShinyTreeMenu(
treedata = treedata,
treemenu_open = r_treemenu_open,
level_icons = "plus")
# For the purpose of displaying the selection functionality
observeEvent(input$treemenu, {
showModal(
modalDialog(
paste("Selected id:", input$treemenu$val,
"| Selected level:", input$treemenu$level,
"| Selected row:", input$treemenu$row)
)
)
})
}
)
}
ok realize that control of hiding/showing branches and subbranches is client side HTML / CSS only.
e.g. /inst/www/shinyTreeMenu.css
ol.tree li input:checked ol{
height:auto;
}
ol.tree li input:checked ol > li{
display:block;
margin:0 0 0.1em 0;
}
the generated check boxes...
<input type="checkbox" id="1" onclick="javascript:Shiny.setInputValue('treemenu_open', {openid:'1', randomVal:Math.random()});" class="shiny-bound-input">
There is no function in shinyTreeMenu yet, that can open/close branches from server side.
I suppose the most clean solution would be to make a function that takes a selected branch as input and send a javascript-snippet to be evaluated on client side. The javascript code should emulate the user has clicked one specific checkbox. Then all other server/client interactions could proceed as normal.
Sorry for not getting back to you before now...
But can see you figured it out yourself and no, you can directly open/close menus from shiny/server side.
The way to do that would probably be using shinyJS to click (shinyjs::click()
) the checkbox you would want to open – and if it is a nested menu item, then adding a loop to it.
That ought to work…
Let me know how it goes? 😊
Hi Emil thanks for this lovely ShinyTreeMenu!!
I feel the documentation do not explain around how to open/close and activate tree links from server side. I have attempted to do so with shinyjs::runjs(js_string2) however I see no visual change on client side.
The overall goal would be to manipulate the tree from somewhere else in a shiny app. what am I missing?
best Soren