I would like to add a Font Awesome 'child' icon twice in my actionButton in Shiny. The following app displays the child once:
library(shiny)
ui <- fluidPage(
actionButton("child","children", icon("child"))
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
I tried the obvious to no avail:
actionButton("child","children", icon(c("child","child")))
I must accept this is quite a niche question.
This has nothing to do with the fact that you want the same icon twice. You just can't pass a vector of names into the icon() function. If you look at the documentation of icon() it says it accepts the name of an icon, not a vector for multiple icons.
To do what you want, you can simply add multiple icons in the label. Something like this
actionButton("child", div(icon("child"), icon("child"), "children"))
Related
This answer explains how can one disable/enable all UI elements in a Shiny app.
Among the two solutions given, the one I am interested in uses the shinyjs package (I'd rather not play with javascript directly).
My problem is that UI elements of the class downloadButton are not listed as elements of input.
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
tagList(
downloadButton("downloadBtn", "Download button"),
actionButton("printBtn", "Print and disable all members of input")
)
)
server <- function(input, output) {
observeEvent(input$printBtn, {
print (names(input))
for(n in names(input))
shinyjs::disable(id=n)
})
}
shinyApp(ui = ui, server = server)
When I click on the "Print all members of input", only "printBtn" is printed ("downloadBtn" is not).
Hence, since downloadButton is not a member of input, disabling it by looping over all the elements of input - and disabling them one by one does not work.
Is there an elegant workaround that can be used in order to disable all of the elements?
I am currently building a shiny app to build biological networks. To build them, you can choose between many different parameters, which i included in different selectInputs or numericInputs.
Is it possible to have some kind of info text, when hovering the mouse over those input fields? I dont want to add 3-4 sentences of text to the title of each select/numericInput.
Thanks :)
If you don't mind an extra package dependancy then you can use bsTooltip from the shinyBS package. Note that the hover tooltip sometimes doesn't show up unless you click on the input in the RStudio viewer pane, but if you run your app in your browser, the hover trigger should work:
library(shiny)
library(shinyBS)
ui <- fluidPage(
selectInput("input1", "Select input", c("choice1", "choice2")),
bsTooltip(id = "input1",
title = "Here is some text with your instructions")
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
I am trying to create a shiny app where users can upload their own data and get a visualization of the network dynamics in their data. I'm using the render.d3movie() function from the ndtv package to create an HTML object from the network with some user input parameters. I want to display this HTML object in one of my tabPanel()s but weirdly, it shows up on every panel instead. I tried with a different HTML file and this one works just fine. To reproduce this, you'll need to download the test and network animation html files and put them in the same directory as the example shiny app code below.
Example:
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
navbarPage("ShinyExample",
tabPanel("TEST", HTML("FirstPage"), includeHTML("test.html")),
tabPanel("TEST2", HTML("SecondPage"), includeHTML("NetworkAnimation.html"))
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
# Stuff to render and save the network Animation happens here
}
# Run the application
shinyApp(ui = ui, server = server)
Expected Behavior:
test.html and NetworkAnimation.html should only be rendered within their respective tabPanel()
Observed Behavior:
test.html is only rendered in it's respective tabPanel() but NetworkAnimation.html is rendered on both tabPanel() s
The network-widget is appended to the body in the NetworkAnimation.html-Javascript:
target = d3.select('body').append('div').style({width: '100%', height: '100%'}).node();.
If you want it to be on Tab 2 only, you can include a div with id and change the JavaScript line, so that it gets appended to your div.
My App looks like this:
ui <- fluidPage(
## Include shinyjs
useShinyjs(),
## Set ID of navbarPage
navbarPage("ShinyExample", id = "navid",
tabPanel("TEST", includeHTML("test.html")),
tabPanel("TEST2",
## Include new DIV here & Set initial height
div(id="appendhere", style="height: 1090px;"),
includeHTML("NetworkAnimation.html"))
)
)
server <- function(input, output) {
observe({
req(input$navid == "TEST2")
runjs('$("#appendhere").resize()')
})
}
# Run the application
shinyApp(ui = ui, server = server)
and the JS is changed to
target = d3.select('#appendhere').append('div').style({width: '100%', height: '100%'}).node();
I also had to include shinyjs, to run some JavaScript when TAB2 is active. The width/height of the svg is calculated when it is rendered and therefore initially 0 (or actually -60).
If you remove the runjs line, you will see that the network is not visible.
By changing the browser size, the network gets redrawn and width/height are updated. Therefore we call $("#appendhere").resize() when TAB2 is active.
There is still the following error in the browser console, but everything seems to work fine.
Uncaught TypeError: a is undefined
Is there a way to check if a download button is disabled using the shinyjs R package? I want to use shinyjs or something similar because they have very easy syntax. This is my package:
server.R:
library(shiny)
library(shinyjs)
library(shinyBS)
shinyServer(function(input, output) {
observe({
shinyjs::disable("download1")
if(shinyjs::is.disabled("download1")){ ## This is what I am trying to do
# Do something
}
})
})
ui.R
shinyUI(fluidPage(
downloadButton("download1")
))
Not directly (well, not easily*).
Buttons can only be disabled when you decide to disable them, so you can have some sort of a reactive variable that holds whether or not the button should be disabled, and whenever you disable the button, you also change the value of that variable. In order to make sure they stay in sync, every time you want to disable the button you can set the variable to mirror that, and then you can use shinyjs::toggleState(condition = variable) so that the disabled state will mirror what the variable says.
Example code to illustrate what I mean:
library(shiny)
ui <- fluidPage(
shinyjs::useShinyjs(),
numericInput("num", "When divisible by 3, disable the button", 1),
actionButton("btn", "button")
)
server <- function(input, output, session) {
values <- reactiveValues(disable = FALSE)
observe({
values$disable <- (input$num %% 3 == 0)
})
observe({
shinyjs::toggleState("btn", condition = !values$disable)
})
}
shinyApp(ui = ui, server = server)
In this app, whenever you want to disable the button, simply set values$disable to FALSE and to enable the button set it to TRUE. To check if the button is currently on or off at any point in time, you can look at the value of values$disable.
*I'm guessing that you wanted a more direct approach to ask the app a question in real time "hey shiny, is button X currently disabled?". You can do that, but it would involve writing custom javascript code to check for the button state, and for custom code to ask javascript that question and to listen for its response. This would work and be guaranteed to be correct, but it's likely overkill for most cases.
I am trying to include a selectizeInput widget in a Shiny app. However, one aspect of its behavior is problematic: each time I make a selection, the box containing the choices closes.
I took a look at the example app here: http://shiny.rstudio.com/gallery/selectize-examples.html. Specifically, input number 2: Multi-select. The selection window remains open in this example, yet I see no differences between that code and mine which would account for the variance in behavior.
For the sake of a reproducible example, I have put together the following code:
ui <- fluidPage(uiOutput("example"))
server <- function(input, output, session){
output$example <- renderUI({
selectizeInput(
inputId="people",
label=NULL,
choices=paste("A", 1:50, sep="_"),
multiple = TRUE,
selected=input$people
)
})
} # close server
shinyApp(ui = ui, server=server)
My guess is that I'm missing something obvious, so here's a chance for an easy answer for someone that knows their way around Shiny. Any help will be greatly appreciated.
When you remove the selected=input$people line, it works as intended.