In a Shiny app, I am trying to have an eventReactive triggered either with an actionbutton OR when the session opens.
I've tryed the below code using session$clientData but it doesn't work.
Also tried to play with toggleModal from shinyBS but still no chance. Any help much appreciated. Thanks!
library(shiny)
ui <- fluidPage(
actionButton("go", "Go"),
numericInput("n", "n", 50),
plotOutput("plot")
)
server <- function(session, input, output) {
randomVals <- eventReactive({input$go
session$clientData}, {
runif(input$n)
})
output$plot <- renderPlot({
hist(randomVals())
})
}
shinyApp(ui, server)
Actually figured this out. On my question above, I tried to simplified my code, and doing so actually fixed the issue...
randomVals <- eventReactive({input$go
session$clientData}
works as expected (i.e. you get a chart when opening the session even without clicking on go), while
randomVals <- eventReactive({session$clientData
input$go}
doesn't work (i.e you need to click on go to get your first chart
So I guess the order in the event {} matters, which I didn't know
Related
Is it possible to see the changes in UI (only the UI and not server) after I make changes in my code, without having to restart the server/refresh the page? If cache needs to be cleared, can that also be done?
You could use reactiveFileReader to regularly source the code you'd save in another file, and renderUI()/uiOutput to display that dynamic UI:
app.R
library(shiny)
ui <- uiOutput("ui")
server <- function(input, output, session) {
ui <- reactiveFileReader(1000, session, "source.R", source)
output$ui <- renderUI(ui())
}
shinyApp(ui = ui, server = server)
source.R
fluidPage(
textInput("text", "text"),
textInput("text2", "text")
)
You still have to find out howto get rid of that "TRUE":
I have the following app, which is just a collapse panel containing an rhandsontable table.
library(shiny)
library(shinyBS)
library(rhandsontable)
ui <- function() {
fluidPage(
bsCollapsePanel(
"Test",
rHandsontableOutput("table")
)
)
}
server <- function(input, output, session) {
output$table <- renderRHandsontable({
rhandsontable(
data.frame(
a = 1:2,
b = 2:3
)
)
})
}
shinyApp(ui, server)
It works as expected: the panel starts with its contents hidden, and if we click it the panel opens and we see the table.
However, there is a noticeable "lag" between the panel opening and the table appearing. I assume this is because the table hadn't been initialized until then, and so all the work actually creating the table only happens at that moment.
If we then close the panel and reopen it, there is no such lag and we can even gradually see the table as the panel reopens.
I don't know if this is a feature or a bug, or who's "fault" it is: rhandsontable, for being lazy in starting up? shinyBS, for being lazy starting its contents up? shiny in general, for only triggering redraws immediately when needed? I'd assume it's rhandsontable, since more basic elements like textInput() don't have this problem, but can't know for sure.
So, is there a way to force this initialization of the table when the app starts up, instead of only when the panel expands?
I've thought of setting the panel to start open and then hack the server to close the panel on startup, but I'm not entirely sure how that'd work... or if it'd even work (if it closes prior to the first redraw, what difference will it make? if it's after the first redraw, that'd imply a flicker on startup, right?).
I think this should do it:
server <- function(input, output, session) {
output$table <- renderRHandsontable({
rhandsontable(
data.frame(
a = 1:2,
b = 2:3
)
)
})
outputOptions(output, "table", suspendWhenHidden = FALSE)
}
I want to make a Shiny App in which the user can press an actionbutton which would then trigger some code on the server side creating a file in the www folder and then opens/downloads the file.
Suppose the file is test.txt (in my case it would be a variety of R, Excel, and exe files which will be copied from different folders on a drive to the www folder).
My first try was to use the actionbutton with the onclick option as shown below
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = "window.open('test.txt')")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
}
shinyApp(ui=ui,server=server)
But this doesn't work since the onclick action is done before the observevent is evaluated.
I then tried to call a function inside to the onclick option as shown below
CreateFileAndLink <- function(){
write.table(c("Test"), file = "www/test.txt")
return("window.open('test.txt')")
}
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = CreateFileAndLink())
)
server <- function(input, output, session){}
shinyApp(ui=ui,server=server)
This works but has the downside that now the file is created when upon opening the Shiny App as opposed to creating the file when the user clicks the actionbutton. This is very inefficient if I were to use this piece of code multiple times in an App with relatively large files.
Maybe it is possible to make sure that the observevent is executed before the onclick-action, or maybe use the onclick option on the server side.
Any help would be greatly appreciated!
Cheers
UPDATE:
I found out that the great shinyjs package by Dean Attali contains a onclick function that might be of help here. I tried to run the code below but it didn't work :/
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
# Call Onclick
onclick("showtxt", "window.open('test.txt')")
})
}
shinyApp(ui=ui,server=server)
I found a solution using the onclick function from the shinyjs package.
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
# Call Onclick
onclick("showtxt", runjs("window.open('test.txt')"))
}
shinyApp(ui=ui,server=server)
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.