How to add hover-over text pop ups over menu list items in jsTreeR?

57 views Asked by At

I've been an active user of the jsTreeR package, inside of Shiny. When running the below skeletal code, a menu of draggable options is presented at the top, and the user drags these items down to the target list labeled ">> Drag here <<" to build a custom sequentially labeled list. Is it possible to build hover-over pop-ups with explanatory text, when hovering over these menu items, as illustrated below? How can this done?

Once an element is dragged down, there is no need for the same hover-over pop-up. Only for elements residing in the "Menu" section at the top.

enter image description here

Code:

library(jsTreeR)
library(shiny)

nodes <- list(
  list(
    text = "Menu",
    state = list(opened = TRUE),
    children = list(
      list(text = "Dog",type = "moveable",state = list(disabled = TRUE)),
      list(text = "Cat",type = "moveable",state = list(disabled = TRUE))
    )
  ),
  list(text = ">> Drag here <<",type = "target",state = list(opened = TRUE))
)

dnd <- list(
  always_copy = TRUE,
  inside_pos = "last", 
  is_draggable = JS(
    "function(node) {",
    "  return node[0].type === 'moveable';",
    "}"
  )
)

mytree <- jstree(
  nodes, dragAndDrop = TRUE, dnd = dnd,
  types = list(moveable = list(), target = list())
)

script <- '
$(document).ready(function(){
  var LETTERS = ["A", "B", "C"];
  var Visited = {};
  $("#mytree").on("copy_node.jstree", function(e, data){
    var oldid = data.original.id;
    var visited = Object.keys(Visited);
    if(visited.indexOf(oldid) === -1){
      Visited[oldid] = 0;
    }else{
      Visited[oldid]++;
    }
    var letter = LETTERS[Visited[oldid]];
    var node = data.node;
    var id = node.id;
    var index = $("#"+id).index() + 1;
    var text = index + ". " + node.text + " " + letter;
    Shiny.setInputValue("choice", text);
    var instance = data.new_instance;
    instance.rename_node(node, text);
  });
});
'

ui <- fluidPage(
  tags$head(tags$script(HTML(script))),
  fluidRow(jstreeOutput("mytree"))
)

server <- function(input, output, session){
  output[["mytree"]] <- renderJstree(mytree)
}

shinyApp(ui, server)
1

There are 1 answers

1
David Jorquera On BEST ANSWER

I. Simplest, direct approach:

  1. Add title attribute to node.
children = list(
      list(text = "Dog",type = "moveable",state = list(disabled = TRUE), a_attr = list(title = "A domesticated carnivorous mammal etc...")),
      list(text = "Cat",type = "moveable",state = list(disabled = TRUE), a_attr = list(title = "A small domesticated carnivorous mammal etc..."))
    )

II. Custom, flawed approach:

  1. Add id to your children of interest:
children = list(
      list(text = "Dog",type = "moveable",state = list(disabled = TRUE), a_attr = list(id = "child_dog")),
      list(text = "Cat",type = "moveable",state = list(disabled = TRUE), a_attr = list(id = "child_cat"))
    )
  1. Use library(shinyBS) to define your tooltips:
ui <- fluidPage(
  tags$head(tags$script(HTML(script))),
  bsTooltip("child_dog", "A domesticated carnivorous mammal etc...",
            "right", options = list(container = "body"), trigger = "hover"),
  bsTooltip("child_cat", "A small domesticated carnivorous mammal etc...",
            "right", options = list(container = "body"), trigger = "hover"),
 
  fluidRow(jstreeOutput("mytree"))
)
  1. However; collapsing and then reopening the parent folder make the tooltip non responsive. I can't seem to find the cause of this; maybe it has to do with javascript changing node's selectors or ids.