Reputation:
I am attempting to output a table in my Shiny app that adds additional rows each time the "Submit" button is clicked. However, instead of accumulating rows, it just replaces the first one. The Shiny documentation didn't help me much (though it's really good).
Here's the UI:
shinyUI(fluidPage(
titlePanel("CSF Payroll App"),
sidebarLayout(
sidebarPanel(
textInput("name", "Put your name here"),
textInput("job", "Job completed"),
dateInput("date", "Input the date you worked"),
numericInput("minutes", "Input the time you worked
(15 minute increments)", 0,0,240,15),
submitButton("Submit")
),
mainPanel(
tableOutput("totalHours")
)
)
))
Here's the server:
shinyServer(function(input, output) {
# Initialize a dataframe to hold all entries.
totalFrame <- data.frame(
Name <- character(),
Job <- character(),
Date <- character(),
Minutes <- numeric(),
stringsAsFactors=FALSE)
colnames(totalFrame) <- c("Name", "Job",
"Date", "Minutes")
# Create a temporary dataframe to take a new entry, reactively,
# then update the totalFrame with each new entry.
addNextEntry <- reactive({
Name <- input$name
Job <- input$job
Date <- as.character(input$date)
Minutes <- input$minutes
tempFrame <- data.frame(Name, Job, Date, Minutes)
totalFrame <- bind_rows(totalFrame, tempFrame)
totalFrame
})
# Update the summary dataframe with new entries as they come in.
output$totalHours <- renderTable({
addNextEntry()
})
})
How do I update the totalFrame in a way that takes reactive content, but accumulates in totalFrame rather than just replacing the first row again and again?
Sample Output: If I put ("Bob", "Cleans", 2017-04-25, 30) into the respective columns of the frame, it renders the table correctly, but then if I try to add another entry, it just replaces the Bob Cleans row.
Upvotes: 0
Views: 205
Reputation: 1751
Solution
Using
reactiveValues
to generate a default and reactive table, combined withobserveEvent
to check if your button is pressed, andsubmitButton
to actionButton
.This does update the initial table (as HubertL mentioned as problem).
Code
library(shiny)
library(dplyr)
ui <- shinyUI(fluidPage(
titlePanel("CSF Payroll App"),
sidebarLayout(
sidebarPanel(
textInput("name", "Put your name here"),
textInput("job", "Job completed"),
dateInput("date", "Input the date you worked"),
numericInput("minutes", "Input the time you worked
(15 minute increments)", 0,0,240,15),
actionButton(inputId = 'button_1',label = 'Add')
),
mainPanel(
tableOutput("totalHours")
)
)
))
server <- function(input, output) {
# default table
totalFrame <- reactiveValues(table = data.frame(
Name = character(),
Job = character(),
Date = character(),
Minutes = numeric(),
stringsAsFactors = FALSE))
# update default table, when actionButton is pressed
observeEvent(input$button_1, {
totalFrame$table <- bind_rows(
totalFrame$table,
data.frame(
Name = input$name,
Job = input$job,
Date = as.character(input$date),
Minutes = input$minutes
)
)
})
table <- reactive({totalFrame$table})
# just render the table
output$totalHours <- renderTable({
table()
})
}
shinyApp(ui = ui, server = server)
Output
before
after (pressing 5x)
Upvotes: 1