My Shiny application runs a script build.R when the user clicks the action button. I would like to inform the user not to close the app while the script is being run. When done, the user is informed that building was successful.
Here's my minimal reproducible code:
library(shiny)
ui <- fluidPage(
actionButton("build", "run the buildscript"),
textOutput("rstatus")
)
server <- function(input, output, session) {
reloadstatus <- reactiveVal("")
observeEvent(input$build, {
reloadstatus("building, do not close the app")
# in the actual app would be source("build.R")
Sys.sleep(1)
reloadstatus("successfully built")
})
output$rstatus <- renderText({
reloadstatus()
})
}
shinyApp(ui, server)
I guess it does not work because Shiny tries to first run the observeEvent till the end before altering the reactiveVal. How can I achieve my desired output (first "reloading..." second "successfully...")?
You can use shinyjs to update the content of message.
library(shiny)
library(shinyjs)
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("build", "run the buildscript"),
p(id = "rstatus", "")
)
server <- function(input, output, session) {
observeEvent(input$build, {
shinyjs::html("rstatus", "building, do not close the app")
# in the actual app would be source("build.R")
Sys.sleep(1)
shinyjs::html("rstatus", "successfully built")
})
}
shinyApp(ui, server)
Related
The below example code "Code" saves to the browser the user slider input from one session to the next, using package shinyStorePlus. I would like the user to be able to clear the saved inputs via a click of the "clear" actionButton(). When the commented-out code in "Code" is uncommented, revealing the clear function in the server section, clicking that actionButton() results in error Warning: Error in envir$session$sendCustomMessage: attempt to apply non-function. However, if I pull the clear data code of clearStore(appId = appid) out of the observer and run the code this way, it works fine in clearing out the saved browser data. As an example, running the "Isolated Clearing Code" at the very bottom, completely outside the observer, clears out the browser data like it should.
What am I doing wrong here with my use of an observer? I've fooled around with using isolate(), making the appid reactive, etc., and nothing seems to work.
Code:
library(shiny)
library(shinyStorePlus)
ui <- fluidPage(
initStore(), br(),
sliderInput("input1",label=NULL,min=1,max=200,value=100),
actionButton("clear","Clear data")
)
server <- function(input, output, session) {
appid <- "application001"
setupStorage(
appId = appid,
inputs = list("input1")
)
# observeEvent(input$clear,{
# clearStore(appId = appid)
# })
}
shinyApp(ui, server)
Isolated Clearing Code:
ui <- fluidPage(
initStore(),
)
server <- function(input, output, session) {
appid <- "application001"
clearStore(appId = appid)
}
shinyApp(ui, server)
This seems to be an issue with shinyStorePlus' code:
> clearStore
function (appId)
{
envir <- parent.frame()
envir$session$sendCustomMessage("clearStorage", appId)
}
using parent.frame() to get the session is unfavorable.
Please check the following instead:
library(shiny)
library(shinyStorePlus)
clearStore <- function(appId, session = getDefaultReactiveDomain()){
session$sendCustomMessage("clearStorage", appId)
}
ui <- fluidPage(
initStore(), br(),
sliderInput("input1",label=NULL,min=1,max=200,value=100),
actionButton("clear","Clear data")
)
server <- function(input, output, session) {
appid <- "application001"
setupStorage(
appId = appid,
inputs = list("input1")
)
observeEvent(input$clear,{
clearStore(appId = appid)
})
}
shinyApp(ui, server)
I left a PR here.
sorry if this is a simple question, but I am quite new to Shiny and even newer to using Modules.
I have a larger application in which one of its pages I use a button to open a Shiny Modal, there are quite a few things going on in this modal, so I made a separate server for it. Inside the modal server are some observeEvent handlers. The problem arises when the user tries to use the modal more than once, as, apparently, opening the modal a second time creates a second instance of its server and then the observeEvents trigger multiple times.
I know that if I use different IDs for the server I can solve this, but I would really like to keep the same ID. In my head, I thought creating a server with the same ID would replace the previous one, but that doesn't seem to be the case. Maybe I just need to delete the previous server when the modal closes(?), I am not sure. Anyway, any help is appreciated.
Here is a reproducible example that shows this behaviour:
Opening the modal a second time and clicking the button makes multiple notifications appear.
modal_server <- function(id){
moduleServer(id,
function(input, output, session){
ns <- session$ns
showModal(modalDialog(actionButton(ns("show_notification"), "Show Notification")))
observeEvent(input$show_notification, {
showNotification("hi")
})
})
}
ui <- fluidPage(
actionButton("show_modal", "Show Modal")
)
server <- function(input, output, session) {
observeEvent(input$show_modal, {
modal_server(id = "modal")
})
}
shinyApp(ui = ui, server = server)
One option to fix your issue would be to move the UI code to the module too and use two observeEvents inside the module server to handle the two events, i.e. showing the modal and showing the notification:
library(shiny)
modal_ui <- function(id) {
ns <- NS(id)
actionButton(ns("show_modal"), "Show Modal")
}
modal_server <- function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- NS(id)
observeEvent(input$show_modal, {
showModal({
modalDialog(
actionButton(ns("show_notification"), "Show Notification")
)
})
})
observeEvent(input$show_notification, {
showNotification("hi")
})
}
)
}
ui <- fluidPage(
modal_ui("modal")
)
server <- function(input, output, session) {
modal_server(id = "modal")
}
shinyApp(ui = ui, server = server)
In my shiny server I am figuring out the name of a markdown file which I want to show in the UI. I know how to pass the file name, as a string, back to the UI but I don't now how to tell includeMarkdown() to treat the string as a file name.
My code so far is below. Any advice?
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
ui <- fluidPage(
includeMarkdown("hello.md"),
br(),
div("File name text:", textOutput("fileNameText", inline = TRUE)),
#includeMarkdown(fileNameText) # this needs help
)
server <- function(input, output, session) {
selectedName <- reactive({
paste0("hello.md") # this is actually more complicated...
})
output$fileNameText <- renderText(
paste0(selectedName())
)
}
shinyApp(ui = ui, server = server)
Your example code works fine, but from your description, I am thinking your asking how to pass a different filename to includeMarkdown() that was created somewhere else in the app, correct?
The first step is to understand includeMarkdown() as a UI element that will change depending on other UI elements (and stuff that happens in server). The solution is to use a placeholder in the ui to hold the place for the includeMarkdown() element, and create that particular element in server using renderUI.
Hopefully you can follow this example. I'm using uiOutput('displayFile') to hold the place for the element that's created in server.
library(shiny)
fileConn<-file("hello.md")
writeLines(c("# Hello","# World"), fileConn)
close(fileConn)
fileConn1<-file("goodbye.md")
writeLines(c("# Goodbye","# Everyone!"), fileConn1)
close(fileConn1)
ui <- fluidPage(
selectInput('file_selection', 'Choose Markdown File:', choices=c('hello.md','goodbye.md')),
uiOutput('displayFile')
)
server <- function(input, output, session) {
output$displayFile <- renderUI({
includeMarkdown(input$file_selection)
})
}
shinyApp(ui = ui, server = server)
I have this app:
library(shiny)
ui <- fluidPage(
textInput("query_text","Type something:"),
actionButton(inputId='query_button',
label="Search",
icon = icon("th"),
onclick = paste("location.href='http://www.example.com?lookfor=",
input$query_text, "'", sep=""))
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
I'd like to update the url with the action button, so when the user types something (for example: paper), it updates the url like this:
http://www.example.com/?lookfor=paper
Any ideias how to do it? Maybe wrapping it on a observeEvent?
Based on your replies to my comment, what you're looking for is the updateQueryString function.
library(shiny)
ui <- fluidPage(
textInput("query_text", "Type something:"),
actionButton(inputId = 'query_button', label = "Search")
)
server <- function(input, output, session) {
observeEvent(input$query_button, {
updateQueryString(paste0("?lookfor=", input$query_text))
})
}
shinyApp(ui, server)
I'm trying to use the relatively new shinyAlert package to see if it offers better results than the sweetalert package but I'm unable to figure out how to get this:
Myvar <- shinyalert input text
from this minimal example.
library(shiny)
library(shinyjs)
library(shinyalert)
ui <- fluidPage(
shinyjs::useShinyjs(),
useShinyalert(),
actionButton("run", "Run", class = "btn-success")
)
server <- function(input, output, session) {
shinyEnv <- environment()
observeEvent(input$run, {
shinyalert('hello', type='input')
})
}
shinyApp(ui = ui, server = server)
My thanks for any help from you geniouses out there.
Here is how you do it:
library(shiny)
library(shinyalert)
ui <- fluidPage(
useShinyalert(),
actionButton("run", "Run", class = "btn-success")
)
server <- function(input, output, session) {
observeEvent(input$run, {
shinyalert('hello', type='input', callbackR = mycallback)
})
mycallback <- function(value) {
cat(value)
}
}
shinyApp(ui = ui, server = server)
It's done using callbacks. You can assign the value to a reactive variable if you'd like.
I had fully documented the package last month and was about to release it, and then my computer crashed before I had a chance to push to github, and lost all progress. I haven't had a chance to work on it again. So sorry that the documentation isn't great yet, the package is still un-released so use at your own risk for now :)
(Notice that you don't need shinyjs for this)
I have no experience with the package shinyalert, but you can achieve what you want with the widely used and well documented modal dialogs from shiny. Maybe you there is a reason for you to stick with shinyalert that I am unaware off, but if not, example code for achieving what you want with modal dialogs:
ui <- fluidPage(
shinyjs::useShinyjs(),
actionButton("run", "Run", class = "btn-success"),
textOutput("output1")
)
server <- function(input, output, session) {
dataModal <- function(failed = FALSE) {
modalDialog(
textInput("input1", "Enter text:",
placeholder = 'Enter text here'
)
)
}
# Show modal when button is clicked.
observeEvent(input$run, {
showModal(dataModal())
})
output$output1 <- renderText({
input$input1
})
}
shinyApp(ui = ui, server = server)
Let me know if this helps!