Stop R Shiny from restoring selected inputs on page refresh - r

Whenever a user refreshes a page, any UI element that has been interacted with retains its new value instead of reverting to its default.
E.g. if I run the app below, change any of the inputs, then refresh the page, the new values are kept rather than the widgets being restored to 'A'.
I can appreciate this is useful in many situations, but is there a way to stop it from within Shiny, or is it controlled by the browser's cache? A hard refresh (ctrl F5) does indeed reset them back to 'A'.
library(shiny)
ui <- fluidPage(
selectInput("select", "Values", LETTERS[1:5], selected='A'),
radioButtons("radio", "Radio", LETTERS[1:5], selected='A'),
checkboxGroupInput("check", "Checkbox", LETTERS[1:5], selected='A')
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)

I cannot really reproduce the problem, here's a GIF of what happens on my system when I refresh the browser (Chrome Version 94.0.4606.71):

Related

How to use a single shiny session after reloading?

I am building a shiny application that will be used by multiple users on a Shiny Open Source Server. Here is a small reprex (from the documentation of shiny)
shinyApp(
ui = fluidPage(
numericInput("n", "n", 1),
plotOutput("plot")
),
server = function(input, output) {
output$plot <- renderPlot( plot(head(cars, input$n)) )
}
)
After running the app, I set the numericInput to 10 and I close the browser. When I open the application again, a new session is started and the value in the numericInput is back at 1. How can I ensure that only one session is active and any user accessing the application, sees this session?
My application is quite large (seperated over several files and modules, with dynamic UI's), so it is not desirable, that every user has to go over all the input fields (>50) every time they start the App.

Can we reset page or object in r shiny without reloading page

Problem1: I created a shiny application in which when user commit any record to database entire page gets reloaded which i don't want i just want to reset/refresh my object in R shiny without entire page reload.Is there any alternative to achieve the same?
Problem2:Also in my application i have one login page so i want when user enters their credentials it should store the credentials in that field so that when user again login to the same page it should not ask to enter credentials along with password not by using browser functionality to remember password.Also when they close the browser and again open new instance of browser it should ask for credentials.
Any help would be appreciated. :)
it is always good if you have any reproducible example for your problem statement.
For your problem 1 there is a package shinyjs. You can use it for reset your object. The sample code for problem 1:
library(shiny)
library(shinyjs)
shinyApp(
ui = fluidPage(
shinyjs::useShinyjs(),
h2("shinyjs demo"),
textInput("name", "Name", ""),
actionButton("submit", "Submit"),
actionButton("reset", "Reset form")
),
server = function(input, output) {
observeEvent(input$submit, {
shinyjs::alert( paste("Thank you!",input$name) )
})
observeEvent(input$reset, {
shinyjs::reset("name")
})
}
)
You can have the documentation here. https://github.com/daattali/shinyjs
For your problem 2 there are few relative things. It can handled by browser also.
You can use this documentation link https://gist.github.com/calligross/e779281b500eb93ee9e42e4d72448189

R/Shiny update input control immediately

I have a Shiny UI which launches some long-running server code. I want to update the input controls with some calculated defaults on page load and have this displayed and used immediately (the long-running code triggers on page load or submit button). The start of my server looks like this:
shinyServer(
function(input, output, session) {
observe({
startDate <- weekdaysBefore(Sys.Date(), 5)
endDate <- weekdaysBefore(Sys.Date(), 1)
updateDateInput(session, 'startDate', value = startDate)
updateDateInput(session, 'endDate', value = endDate)
})
# long-running calculations
However, the controls only update after everything else runs. This means the UI displays the initial values of the controls instead of the calculated values above whilst the code is running, the server code runs with the initial values, then when the results are presented the controls update to show the desired values - but not the ones being displayed. The documentation for updateDateInput says:
The input updater functions send a message to the client, telling it
to change the settings of an input object. The messages are collected
and sent after all the observers (including outputs) have finished
running.
I would like to update the controls without this collection and/or page load. How is this possible?
You could initialize your UI with the appropriate values. The initial render will then be with the values you've selected.
ui <-dashboardPage(
dashboardHeader(...),
dashboardSidebar(
dateRangeInput("dates",
"Date range",
start = as.character(Sys.Date()-4),
end = as.character(Sys.Date())),
),
dashboardBody(
.
.
.
)
)

Limiting the number of users in a locally hosted R shiny app

I'd like to limit the number of users of my locally hosted r shiny app to one user at any one time.
So ideally when a second user attempted to run the app at the same time (users access the app by typing the local IP into the address field) the app would display a default message and stop any further progress. Nullifying any other user commands may not matter if the only thing shown upon entry is this denial message.
The content of the app doesn't matter so we can use this app as an example: http://shiny.rstudio.com/gallery/tabsets.html
Thanks for any help or info you can give.
I wouldn't recommend doing this, I think it's very dangerous, but there are ways you could hack this together. Here's one solution (as I said, it's hacky and I wouldn't do it myself). The basic idea is to have a global variable that keeps track of whether or not someone is using the app. If nobody is using the app, show the app and turn on the flag and make sure to turn off the flag when the user exits.
shinyBusy <- FALSE
runApp(shinyApp(
ui = fluidPage(
shinyjs::useShinyjs(),
shinyjs::hidden(
h1(id = "busyMsg", "App is busy")
),
shinyjs::hidden(
div(
id = "app",
p("Hello!")
)
)
),
server = function(input, output, session) {
if (shinyBusy) {
shinyjs::show("busyMsg")
} else {
shinyBusy <<- TRUE
session$onSessionEnded(function() shinyBusy <<- FALSE)
shinyjs::show("app")
}
}
),
launch.browser = TRUE)
Note: in order to show/hide app elements, I'm using a package that I wrote shinyjs

Timing events when session ends

I am building a Shiny application, where I want to stop the (local) server when the client is closed. A simple way to achieve this is to include this in the shinyServer function:
session$onSessionEnded(function() {
stopApp()
})
A downside to this approach is if the user decides to hit refresh, then the app dies.
I have tried various workarounds, using e.g. reactiveTimer/invalidateLater to check for connections at certain intervals. However, these take a session reference (they are specific to the session), and so nothing will execute after onSessionEnded.
Is there a way to have a "global" server timer that executes regularly, and coould check for active connections? Or another way to achieve automatic application shut-down but which allows for a refresh of the page?
You could add an actionButton and some code on the server to stop the app when the button is clicked. For example:
runApp(list(
ui = bootstrapPage(
actionButton('close', "Close app")
),
server = function(input, output) {
observe({
if (input$close > 0) stopApp()
})
}
))
However, this won't automatically close the browser window (unless you're viewing with RStudio's built-in browser window). To do that, you need to add some Javascript to the actionButton.
runApp(list(
ui = bootstrapPage(
tags$button(
id = 'close',
type = "button",
class = "btn action-button",
onclick = "setTimeout(function(){window.close();},500);",
"Close window"
)
),
server = function(input, output) {
observe({
if (input$close > 0) stopApp()
})
}
))
Of course, this won't stop the app when the user closes the window some other way. I believe it's also possible to detect window close events in the browser, and then you may be able to set an input value (which goes to the server) at that time, but I don't know whether it'll get to the server before the window is closed and the Javascript stops running.

Resources