library(shiny) | |
# Define the fields we want to save from the form | |
fields <- c("name", "used_shiny", "r_num_years") | |
# Save a response | |
# ---- This is one of the two functions we will change for every storage type ---- | |
saveData <- function(data) { | |
data <- as.data.frame(t(data)) | |
if (exists("responses")) { | |
responses <<- rbind(responses, data) | |
} else { | |
responses <<- data | |
} | |
} | |
# Load all previous responses | |
# ---- This is one of the two functions we will change for every storage type ---- | |
loadData <- function() { | |
if (exists("responses")) { | |
responses | |
} | |
} | |
# Shiny app with 3 fields that the user can submit data for | |
shinyApp( | |
ui = fluidPage( | |
DT::dataTableOutput("responses", width = 300), tags$hr(), | |
textInput("name", "Name", ""), | |
checkboxInput("used_shiny", "I've built a Shiny app in R before", FALSE), | |
sliderInput("r_num_years", "Number of years using R", 0, 25, 2, ticks = FALSE), | |
actionButton("submit", "Submit") | |
), | |
server = function(input, output, session) { | |
# Whenever a field is filled, aggregate all form data | |
formData <- reactive({ | |
data <- sapply(fields, function(x) input[[x]]) | |
data | |
}) | |
# When the Submit button is clicked, save the form data | |
observeEvent(input$submit, { | |
saveData(formData()) | |
}) | |
# Show the previous responses | |
# (update with current response when Submit is clicked) | |
output$responses <- DT::renderDataTable({ | |
input$submit | |
loadData() | |
}) | |
} | |
) |
Hello Dean,
Love your coding style, have been reviewing your "Basic Shiny app without data storage".
Q1. When I quit the RStudio session, the RESPONSE data remains in the OS RAM?
Hi Dean,
can you explain how the bubbling trigger of the submit button is listened to and caught in the code chunk of rendering responses?
Why does the input$submit
appear in the renderDataTable
part? I would rather see this as better suited case for another orberveEvent
.
output$responses <- DT::renderDataTable({
input$submit #when this is not here, the app wont render responses, however the event listening is not explicitly defined at this point
loadData()
})
Also the formData
seems not to be executed when the inputs stay the same, is it because of lazy loading? I figure this by adding a print statement to the formData
code:
formData <- reactive({
print("formData executed")
data <- sapply(fields, function(x) input[[x]])
data
})
I think there a some internals hidden to my sight I would like to understand.
I'm using the same code but all my entries are NULL when the Submit Button is clicked. Any thoughts as to why this might happen?
I use exactly the same code as in the Gist and for some reason from the 3rd input the data table is lagging by one row. For example, if I submit d1 for a name it shows immediately, then d2 for a name which shows up immediately as well, but when I submit the 3rd value then it does not show up in the data table immediately and only sows up after I submit the 4th value. From now the table is lagging by one.
Do you have any clue why this is happening?
As an alternative I used
reactiveVal()
which nicely does the job and does not mess with.GlobalEnv