Instantly share code, notes, and snippets.

@daattali /app.R
Last active Dec 3, 2018

Embed
What would you like to do?
Basic form-submission shiny app used in "Persistent data storage in shiny apps" article http://deanattali.com/blog/shiny-persistent-data-storage/
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()
})
}
)
@hansthompson

This comment has been minimized.

Copy link

hansthompson commented Jul 2, 2015

Sorry if I am the only one who doesn't know this but what is "<<-"?

@klittle314

This comment has been minimized.

Copy link

klittle314 commented Sep 8, 2015

copied the script and attempted to run today (Windows 7, R V3.2.2, RStudio 0.99.473, shiny v 0.12.2 and shinyapps 0.3.63).

Error message:

shiny::runApp()

Listening on http://127.0.0.1:4135
Error in if (is.null(data) || ncol(data) == 0) { :
missing value where TRUE/FALSE needed

Since this conditional execution does not appear in the app.R script, it must be somewhere else, which I can't find...The error message suggests that the object data is missing so the condition can't be evaluated.with is.null(data) OR ncol(data)

SOLUTION: found that the object responses is the name of a function in the utils namespace. When I changed the object to "responses1" , the code executes....

So the problem seems to arise when the object data is assigned to responses which is a function object not a data object....

thanks for your blog directions, I will keep learning now!!

@RajaAsyraf

This comment has been minimized.

Copy link

RajaAsyraf commented Jan 11, 2017

Hi hansthompson,

For your question about "<<-" operation, using "<<-", you can define a global variable and assign to the reactive function.

Refer here: http://stackoverflow.com/questions/15327506/r-shiny-how-to-save-input-data-to-the-server-or-access-input-variables-globally

@etwatson

This comment has been minimized.

Copy link

etwatson commented Mar 11, 2017

Hi,

I've made a change, adding a dateInput() to the input, but the form data is not in date format. How can i specify that the field "date" is as.Date() in the "responses" table?

screen shot 2017-03-11 at 12 15 19 pm

@john-magrini

This comment has been minimized.

Copy link

john-magrini commented Jun 17, 2017

Any solves for ewatson's issue above? I'd be interested because I am having the same issue. I've tried using cast num > char > date per a suggestion and that didn't work, I still was getting the numeric values of dataInputs.

@angelovangel

This comment has been minimized.

Copy link

angelovangel commented Jun 26, 2017

@etwatson,
this is a datatable (DT), so check this out (I don't know your code so this is just a general structure):
DT::renderDataTable({ datatable() %>% formatDate("date", toDateString) })
Here the helper functions of DT are explained:
https://rstudio.github.io/DT/functions.html

@armenic

This comment has been minimized.

Copy link

armenic commented Dec 2, 2018

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

library(shiny)

# Define the fields we want to save from the form
fields <- c("name", "used_shiny", "r_num_years")

# Shiny app with fields that the user can submit data for
shinyApp(
    ui = fluidPage(
        tableOutput("res"), 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) {
        
        rv <- reactiveVal()
        
        # When the Submit button is clicked, save the form data
        observeEvent(input$submit, {
            
            df <- as.data.frame(
                t(sapply(fields, function(X) input[[X]]))
            )
            
            rv(rbind(rv(), df))
        })
        
        # Show the previous res
        # (update with current response when Submit is clicked)
        output$res <- renderTable({
            input$submit
            rv()
        })     
    }
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment