I'm developing a shiny app and I want to add an "infobox" next to a selectInput(). Basically I want to add a small "info" icon to the selectInput() label and when a user move the mouse hover the info icon, a box with some text appears. I've found here on stackedoverflow a solution with tags$span and tags$i and if I add only text it works fine, but if I want to add an html link, or simply another tags (like tags$strong), it doesn't work. Here a reproducible example.
library(shiny)
shinyApp(
ui = fluidPage(
br(),
selectInput("works",
label = tags$span(
"This works",
tags$i(
class = "glyphicon glyphicon-info-sign",
style = "color:#0072B2;",
title = "Further information "
)),
choices = c("a","b")),
selectInput("notwork",
label = tags$span(
"This not works",
tags$i(
class = "glyphicon glyphicon-info-sign",
style = "color:#0072B2;",
title = list("Further information ",
tags$a(href = "https://www.google.com", "here", .noWS = "after"))
)),
choices = c("a","b")),
selectInput("notwork2",
label = tags$span(
"Neither this",
tags$i(
class = "glyphicon glyphicon-info-sign",
style = "color:#0072B2;",
title = p("Further information ",
strong("here"))
)),
choices = c("a","b")),
),
server = function(input, output) {
}
)
It looks I can't pass any other html tags to that value.
You try to put HTML in a normal HTML title attribute, which is never supported. what you need is some sort of Tooltip. You can use bsButton in combination with bsPopover from the ShinyBS package. I did not bother for the styling, but I am pretty sure you can get it done from here.
library(shiny)
library(ShinyBS)
shinyApp(
ui = fluidPage(
br(),
selectInput("works",
label = tags$span(
"This works",
tags$i(
class = "glyphicon glyphicon-info-sign",
style = "color:#0072B2;",
title = "Further information "
)),
choices = c("a","b")),
selectInput("worksnow",
label = tags$span("This works now too", bsButton("thisworks", label = "", icon = icon("info"), style = "info", size = "extra-small")),
choices = c("a","b")
),
bsPopover(
id = "thisworks",
title = "More information",
content = paste0(
"Any HTML can be here ",
a("ShinyBS", href = "https://ebailey78.github.io/shinyBS/index.html", target="_blank")
),
placement = "right",
trigger = "hover",
options = list(container = "body")
)
),
server = function(input, output) {
}
)
Related
Hi,
I need to put a logo in this red place, I already tried:
cabecalho <- dashboardHeader(title = "Test", titleWidth = '300px')
cabecalho$children[[2]]$children <- tags$a(href='http://mycompanyishere.com',
tags$img(src='logo.png',height='50',width='100'))
But this gave me the image inside the "Test" title.
I solved this problem just adding this to dashboardHeader:
dashboardHeader(title = "Report", titleWidth = '240px',
tags$li(a(href = 'http://www.site.com.br',
img(src = 'logo.png',
title = "Company Home", height = "30px"),
style = "padding-top:10px; padding-bottom:10px; padding-right:17px;"),
class = "dropdown")
)
I would like to change the default arrow direction (as in the attached pic), so it will point to the right.
this is the current code:
sidebarMenu(
menuItem("Market data", tabName = "market data", icon = icon("users"), startExpanded = TRUE,
menuSubItem("Performance", tabName = "history", icon = icon("calendar-day")),
menuSubItem("SMP", tabName = "SMP", icon = icon("dollar-sign"))
),
menuItem("Consumer 1", tabName = "consumer1", icon = icon("user"), startExpanded = FALSE,
menuSubItem("Consumption", tabName = "consumption", icon = icon("history")),
menuSubItem("Profile", tabName = "profile", icon = icon("poll-h")),
menuSubItem("Forecast engine", tabName = "forecast", icon = icon("brain"))
)
Thanks in advance
General
In general, to change the defaults in shinydashboard you need to find the correct CSS tags for these elements and then add your own custom CSS file to overwrite the default.
If you plan on making a lot of these changes, the shinydashboard framework might not be right for you.
Specific solution to your question
With some poking around in the browser, you'll see that the tag for these arrows are .fa-angle-left:before. The symbol showed is defined with the following CSS:
.fa-angle-left:before{content:"\f104"}
To change it to a right arrow we need to change \f104 to \f105:
As noted in the documentation, you can add your own CSS-file as such:
Add the file www/custom.css to the same folder as your Shiny dashboard is located.
Add the following code to it:
.fa-angle-left:before{content:"\f105"}
If you want the arrow to still point down after you click it you also need to add
.sidebar-menu li.active>a>.fa-angle-left, .sidebar-menu li.active>a>.pull-right-container>.fa-angle-left {
transform: rotate(90deg);
}
When this is done, you need to add the following code to your sidebarMenu:
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "custom.css")
)
Working example
app.R
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
dashboardSidebar(
sidebarMenu(
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "custom.css")
),
menuItem(
"Market data",
tabName = "market data",
icon = icon("users"),
menuSubItem("SMP", tabName = "SMP", icon = icon("dollar-sign"))
)
)
)
),
dashboardBody()
)
server <- function(input, output) {}
shinyApp(ui, server)
www/custom.css
.fa-angle-left:before{content:"\f105"}
.sidebar-menu li.active>a>.fa-angle-left, .sidebar-menu li.active>a>.pull-right-container>.fa-angle-left {
transform: rotate(90deg);
}
I'm having trouble with the formats of conditional panels affecting other conditional panels. Below is reproducible code, and at the bottom are images better explaining the issue. In the fuller App this code derives from, the problem is more obvious and makes it look sloppy (in the fuller App, there are multiple screens the user clicks through as the user scrolls to the right along the shaded bar (Well Panel) at the top just underneath the tab label, and the misalignment gets more pronounced as the user scrolls to the right).
The problem is: as the user scrolls right through the Glide Controls / Well Panels to make selections, the Well Panels (at the top with radio buttons) begin to misalign with the table and/or plots that appear beneath. The misalignment gets more pronounced as the user scrolls right. This misalignment isn't as apparent in this reproducible example, but is more pronounced in the fuller App this derives from where there are multiple "screens" or Well Panels at the top for the user to scroll through and where there are data tables and/or plots presented underneath in the main panel.
For sake of simplicity all server code is eliminated in this example (no plots, no tables), as the issue still presents without the server code.
If I comment-out other conditional panels (marked "###" in the reproducible code) the misalignment goes away. So how can I make the conditional panels independent of one another, as a way of eliminating this misalignment? I'm open to any other suggestions for eliminating this misalignment.
The basic structure of the App is the user makes "big choices" along the sidebar panel, and makes more "refined choices" only the top bar underneath the tab label using Glide Controls/Well Panels etc. for a carousel affect.
Reproducible code:
library(shiny)
library(shinyglide)
library(shinyjs)
library(shinyWidgets)
ui <-
fluidPage(
useShinyjs(),
tags$style(".glide-controls { position: absolute; top: 8px; right: 14px; width: 160px; }"),
titlePanel("Hello"),
sidebarLayout(
sidebarPanel(selectInput("selectData", h5(strong("Select data to view:")),choices = list("Stratification","DnL balances"),selected = "Stratification")),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
div(style = "margin-top:10px"),
conditionalPanel(condition = "input.selectData == 'Stratification'",
fluidRow(
column(12,
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(
wellPanel(
radioButtons(
inputId = 'groupStrats',
label = NULL,
choiceNames = c('Calendar period','MOB'),
choiceValues = c('Period','MOB'),
selected = 'Period',
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
),
screen(
wellPanel(
radioButtons(
inputId = 'stratsView',
label = NULL,
choices = list("Table view" = 1,"Plot view" = 2),
selected = 1,
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
)
)
)
),
### Deleting next line resolves the well panel issue ###
conditionalPanel(condition = "input.stratsView == 2",fluidRow(column(12, plotOutput("stratPlot"))))
),
### Deleting the following conditional panel also resolves the well panel issue ###
conditionalPanel(condition = "input.selectData == 'DnL balances'",
fluidRow(
column(12,
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(
wellPanel(
radioButtons(
inputId = 'groupBal',
label = NULL,
choiceNames = c('Calendar period','MOB'),
choiceValues = c('Period','MOB'),
selected = 'Period',
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
)
)
)
)
), # closes conditional panel
### Deleting the following conditional panel (or either checkbox... or selectize...) also resolves the well panel issue ###
conditionalPanel(condition = "input.selectData == 'Level 1 data'",
panel(
checkboxGroupInput(
inputId = "vars",
label = "Filter by (default view is all data):",
choices = c("Period", "MOB"),
selected = c("Period", "MOB"),
inline = TRUE),
selectizeGroupUI(
id = "my-filters",
params = list(Period = list(inputId = "Period", title = "Period:"),
MOB = list(inputId = "MOB", title = "MOB:"))
), # closes above selectize...
status = "primary"
)
) # closes conditional panel
), id = "tabselected"
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
Actually this is the same issue as here.
The conditionalPanels are visible for a very short time when first invoking the app.
This causes a vertical scrollbar to appear and leads to the misalignment.
Use style = "display: none;" to render the conditionalPanels hidden on startup (where needed) and please leave a thumbs up or other feedback here.
library(shiny)
library(shinyjs)
library(shinyglide)
library(shinyWidgets)
ui <-
fluidPage(
useShinyjs(),
tags$style(".glide-controls { position: absolute; top: 8px; right: 14px; width: 160px; }"),
titlePanel("Hello"),
sidebarLayout(
sidebarPanel(selectInput("selectData", h5(strong("Select data to view:")),choices = list("Stratification","DnL balances"),selected = "Stratification")),
mainPanel(
tabsetPanel(
tabPanel("Private data", value = 1,
div(style = "margin-top:10px"),
conditionalPanel(condition = "input.selectData == 'Stratification'",
fluidRow(
column(12,
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(
wellPanel(
radioButtons(
inputId = 'groupStrats',
label = NULL,
choiceNames = c('Calendar period','MOB'),
choiceValues = c('Period','MOB'),
selected = 'Period',
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
),
screen(
wellPanel(
radioButtons(
inputId = 'stratsView',
label = NULL,
choices = list("Table view" = 1,"Plot view" = 2),
selected = 1,
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
)
)
)
),
### Deleting next line resolves the well panel issue ###
conditionalPanel(condition = "input.stratsView == 2", style = "display: none;", fluidRow(column(12, plotOutput("stratPlot"))))
),
### Deleting the following conditional panel also resolves the well panel issue ###
conditionalPanel(condition = "input.selectData == 'DnL balances'", style = "display: none;",
fluidRow(
column(12,
glide(
custom_controls = div(class = "glide-controls", glideControls()),
screen(
wellPanel(
radioButtons(
inputId = 'groupBal',
label = NULL,
choiceNames = c('Calendar period','MOB'),
choiceValues = c('Period','MOB'),
selected = 'Period',
inline = TRUE),
style = "padding-top: 12px; padding-bottom: 0px;")
)
)
)
)
), # closes conditional panel
### Deleting the following conditional panel (or either checkbox... or selectize...) also resolves the well panel issue ###
conditionalPanel(condition = "input.selectData == 'Level 1 data'", style = "display: none;",
panel(
checkboxGroupInput(
inputId = "vars",
label = "Filter by (default view is all data):",
choices = c("Period", "MOB"),
selected = c("Period", "MOB"),
inline = TRUE),
selectizeGroupUI(
id = "my-filters",
params = list(Period = list(inputId = "Period", title = "Period:"),
MOB = list(inputId = "MOB", title = "MOB:"))
), # closes above selectize...
status = "primary"
)
) # closes conditional panel
), id = "tabselected"
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
I have this shiny app with 4 menuItem. One is named "Login" and tabA, tabB, and tabC are under a conditionalPanel and only appear when a login is successfully done.
Can someone give a hint on why the UI has changed? Because all 4 tabs should look exactly as the first one.
ui.R code:
menuItem('Login', tabName = 'Login', icon = icon('fa fa-address-book')),
conditionalPanel(" 'TRUE' === 'TRUE' ",
menuItem("tabA", tabName = "tabA", icon = icon("fa fa-book")),
menuItem("tabB", tabName = "tabB", icon = icon("fa fa-line-chart")),
menuItem("tabC", icon = icon("fa fa-database")))
Thank you in advance
One option should be to wrap with sidebarMenu
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(
title = "Shiny"
),
dashboardSidebar(
sidebarMenu(id="menu",
menuItem('Login', tabName = 'Login', icon = icon('user-o')),
conditionalPanel(" 'TRUE' === 'TRUE' ",
sidebarMenu(menuItem("tabA", tabName = "tabA", icon = icon("quora")),
menuItem("tabB", tabName = "tabB", icon = icon("superpowers")),
menuItem("tabC", tabName = "tabC", icon = icon("podcast"))))
)
),
dashboardBody(
tabItems(
tabItem("Login",h1("login")),
tabItem("tabA",h1("a")),
tabItem("tabB",h1("b")),
tabItem("tabC", h1("c"))
)
)
)
server <- function(input, output) {
observe(print(input$menu))
}
shinyApp(ui,server)
giving output
In my shiny app I want to add an option to let users jump to a specific element in the app (a table, a plot, just anything with an id), on current or different tab, by clicking on infoBox (or any other object I want).
My solution was to surround infoBox with div and add thehref=#id_of_element attribute. Unfortunately this solution works only for tabs with an extra "data-toggle" = "tab" attribute (it also does not change the opened tab to active), but that's not what I want.
My question is: how can I add the mentioned option and why this solution isn't working? Here is a small example what I want to do:
UI
library(shiny)
library(shinydashboard)
shinyUI(
dashboardPage(
skin = "blue",
dashboardHeader(title = "Example"),
dashboardSidebar(
sidebarMenu(id = "sidebarmenu",
menuItem("Tab1", icon = icon("line-chart"),
menuSubItem("SubTab1", tabName = "sub1", icon = icon("bar-chart")),
menuSubItem("SubTab2", tabName = "sub2", icon = icon("database"))),
menuItem("Tab2", tabName = "tab2", icon = icon("users"))
)
),
dashboardBody(
tabItems(
tabItem(tabName = "sub1",
tags$div(href="#s2t2",
infoBox(value = "Go to table 2 in SubTab2 (not working)",title = "Click me")),
tags$div(href="#shiny-tab-tab2", "data-toggle" = "tab",
infoBox(value = "Go to Tab2 (this works)",title = "Click me"))
),
tabItem(tabName = "sub2",
tableOutput("s2t1"),
tableOutput("s2t2")
),
tabItem(tabName = "tab2",
tableOutput("t2t1"),
tableOutput("t2t2")
)
)
)
)
)
SERVER:
shinyServer(function(input, output,session) {
output$s2t1<- renderTable(mtcars)
output$s2t2<- renderTable(mtcars)
output$t2t1<- renderTable(mtcars)
output$t2t2<- renderTable(mtcars)
} )
I found my answer:
$(document).ready(function() {
$("#div1").click(function() {
$(".sidebar-menu a[href=\'#shiny-tab-tab2\']").tab("show");
setTimeout(function(){
var top = $("#t2t2").position().top;
$(window).scrollTop( top );
}, 300);
});
});
where div1 is div around infoBox