I have an app with a sidebar from shinydashboard
and multiple tabs in a tabBox
. In the sidebar I want to have an info button - and when you hover over it, a different text depending on which tab you're currently on should display.
One solution that works, but is in my opinion pretty ugly, is to define identical infobuttons with different tooltips for each tab, like so:
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tippy)
ui <- dashboardPage(
skin = 'blue',
dashboardHeader(),
dashboardSidebar(width = 275,
sidebarMenu(conditionalPanel(condition = "input.my_tabbox == 'panel_1'",
actionBttn(inputId = "info_button",label = NULL,style = 'material-circle',color = 'primary',
icon = icon('info')),
tippy_this("info_button",tooltip = "You are on panel 1",trigger = 'mouseenter focus',
placement = 'right')),
conditionalPanel(condition = "input.my_tabbox == 'panel_2'",
actionBttn(inputId = "info_button_2",label = NULL,style = 'material-circle',color = 'primary',
icon = icon('info')),
tippy_this("info_button_2",tooltip = "You are on panel 2",trigger = 'mouseenter focus',
placement = 'right')))),
dashboardBody(
fluidRow(column(width = 12,
tabBox(width = 12,id = "my_tabbox",
tabPanel(title = "Panel 1",value = "panel_1"),
tabPanel(title = "Panel 2",value = "panel_2"))))
)
)
server <- function(input,output){}
shinyApp(ui = ui,server = server)
However, if I ever want to change the looks or behaviour of the info button, I'd have to redo this for every single tab. So I looked for a different solution: Is it possible to define the button only once and just change the tooltip text? I tried to outsource the tippy_this
with renderUI
, but it did not work, this is a failed attempt of mine:
ui <- dashboardPage(
skin = 'blue',
dashboardHeader(),
dashboardSidebar(width = 275,
sidebarMenu(actionBttn(inputId = "info_button",label = NULL,style = 'material-circle',color = 'primary',icon = icon('info')),
uiOutput("my_tippy"))),
dashboardBody(
fluidRow(column(width = 12,
tabBox(width = 12,id = "my_tabbox",
tabPanel(title = "Panel 1",value = "panel_1"),
tabPanel(title = "Panel 2",value = "panel_2"))))
)
)
get_tippy_sentence <- function(tabbox_input){
if(tabbox_input == "panel_1"){
return("You are on panel 1")
}else if(tabbox_input == "panel_2"){
return("You are on panel 2")
}
}
server <- function(input,output){
output$my_tippy <- renderUI({
tippy_this("info_button",tooltip = get_tippy_sentence(input$my_tabbox),trigger = 'mouseenter focus',placement = 'right')
})
}
I also tried to make the tooltip a reactive
and change it with an observeEvent(input$my_tabbox,{...})
, but none of those iterations ever managed to display anything different for the second tab.
This is possible if you use a little bit of custom JS
. In what follows, similar to your example the text of the tippy
is generated dynamically depending on which tab is active. Initially, tab 1 is displayed.
$(document).ready(function() {
tippy('#info_button', {
content: 'You are on panel 1',
placement: 'right'
});
$('#my_tabbox').on('shown.bs.tab', function() {
var panelText = $('#my_tabbox').children('.active').prop('innerText');
var hoverText = 'You are on ' + panelText;
document.querySelector('#info_button')._tippy.setContent(hoverText);
});
})
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tippy)
js <- "
$(document).ready(function() {
tippy('#info_button', {
content: 'You are on panel 1',
placement: 'right'
});
$('#my_tabbox').on('shown.bs.tab', function() {
var panelText = $('#my_tabbox').children('.active').prop('innerText');
var hoverText = 'You are on ' + panelText;
document.querySelector('#info_button')._tippy.setContent(hoverText)
});
})
"
ui <- dashboardPage(skin = 'blue',
dashboardHeader(),
dashboardSidebar(width = 275,
sidebarMenu(
actionBttn(
inputId = "info_button",
label = NULL,
style = 'material-circle',
color = 'primary',
icon = icon('info')
),
tippy_this(
"info_button",
tooltip = "",
trigger = 'mouseenter focus',
placement = 'right'
)
)),
dashboardBody(tags$head(tags$script(JS(js))),
fluidRow(column(
width = 12,
tabBox(
width = 12,
id = "my_tabbox",
tabPanel(title = "Panel 1", value = "panel_1"),
tabPanel(title = "Panel 2", value = "panel_2")
)
)))
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)