Turning off popovers

54 views
Skip to first unread message

Roger Day

unread,
Aug 17, 2017, 1:59:35 PM8/17/17
to Shiny - Web Framework for R
This should be a goal of fairly wide interest;
Implement popovers (or tooltips), 
and a toggle allowing user so turn them off, and on again, at will.
Works in a way, but in curious fashion.


The popovers are implemented in a function addAllPopovers()
beginning with     cat("addAllPopovers\n")
with 19 commands like
      addPopover(session, 'popFavoriteDose', title="Dose", 
               content="Select a dose by clicking on plot (left),<br>or type or scroll here.")
 The code to turn them all off is:
stopAllPopovers = function(){
  cat("stopAllPopovers\n")
  output$JSevaluation = renderUI({
      scriptString = paste(
        'stopAllPopoversString =
            "$(\\"*[id^=\\\'pop\\\']\\").popover(\\\'destroy\\\');" ;',
        'eval(stopAllPopoversString); '
      )
      tags$script( scriptString )
    } ) 
  }
Works great. 
The javascript created is 
stopAllPopoversString =
       "$(\"*[id^=\'pop\']\").popover(\'destroy\');" ; 
        eval(stopAllPopoversString);
And by golly, in a JS console it works.
And, stopAllPopovers works... in a fashion. 

So with a checkbox for toggle, we have
  observeEvent(input$togglePopovers, {
    cat('input$togglePopovers a', input$togglePopovers, '\n')
    if(input$togglePopovers) 
      addAllPopovers()
    else 
      stopAllPopovers()
  })
Clicking the checkbox does indeed call the expected functions, like so:
input$togglePopovers  FALSE 
stopAllPopovers
input$togglePopovers  TRUE 
addAllPopovers
input$togglePopovers  FALSE 
stopAllPopovers
input$togglePopovers  TRUE 
addAllPopovers
Etc. So what's wrong?
1) It takes TWO clicks on the toggle to turn on, or turn off, the popovers.
So sometimes  stopAllPopovers enables the popovers, and sometimes  addAllPopovers disables them!
2) Sometimes, upon restarting the program, not all the popovers are enabled.  Then, after two clicks on the checkbox,
the disabled ones are enabled, and the enabled and disabled. The division into two sets of popovers differs each time.

By the way, the bottom of the app window has my shinyDebuggingPanel, which is super-useful for running either R or JS code 
inside the app.  Toggle it open, and away you go. For example, you can test addAllPopovers(), stopAllPopovers() directly.

Roger Day

unread,
Sep 11, 2017, 9:49:41 PM9/11/17
to Shiny - Web Framework for R
It turns out that bootstrap JS code for popovers and tooltips is buggy.
This link helped me solve the problem,
including replacement JS.
The solution is implemented in my package DUE, in the app DUEshiny.

Here are the sources to credit, and some details.


https://stackoverflow.com/questions/27238938/bootstrap-popover-destroy-recreate-works-only-every-second-time


Here is the code for shinyBS.addTooltip

function (id, type, opts) {

  var $id = shinyBS.getTooltipTarget(id);

  var dopts = {html: true};

  opts = $.extend(opts, dopts);

  

  if(type == "tooltip") {

    $id.tooltip("destroy");

    $id.tooltip(opts);

  } else if(type == "popover") {

    $id.popover("destroy");

    $id.popover(opts);

  }

  

}


Here is the suggested replacement, from https://github.com/ebailey78/shinyBS/issues/88:


shinyBS.addTooltip = function(id, type, opts) {

  var $id = shinyBS.getTooltipTarget(id);

  var dopts = {html: true};

  opts = $.extend(opts, dopts);


  if(type == "tooltip") {

    $id.tooltip("destroy");

    setTimeout(function() {$id.tooltip(opts);},200);

  } else if(type == "popover") {

    $id.popover("destroy");

    setTimeout(function() {$id.popover(opts);},200);

  }

}

and add the following to your ui: (assuming the file is named pop_patch.js)

singleton(tags$head(tags$script(src = "pop_patch.js"))),

Reply all
Reply to author
Forward
0 new messages