Search code examples
rshinyshinyappsshiny-reactivity

How to add rows to R Shiny table


I am trying to build a form with R Shiny which will be used to populate a table once the action button at the end of the form is clicked. What I have not been able to figure out is how to pick up the data in the form and add it to a new row in the table. Right now, it just keeps updating the first row with whatever is in the form. I have reproduced a simple version of the code here:


    #ui.r
    
    library(shiny)
    
    shinyUI(fluidPage(
      # Application title
      titlePanel("Test App"),
      
      sidebarPanel(
        numericInput("x", "Enter Value of X", 1),
        numericInput("y", "Enter Value of Y", 1),
        actionButton("add_data", "Add Data", width="100%")
      ),
      mainPanel(
        tableOutput("xy_Table")
      )
    )
    )

    #server.R

    library(shiny)
    library(tidyverse)
    
    shinyServer(function(input, output) {
    
      x <- vector("numeric")
      y <- vector("numeric")
      xyTable <- tibble(x, y)
      e <- reactive(input$x)
      f <- reactive(input$y)
      
      eventReactive(input$add_data, {
        xyTable %>% add_row(x=e(), y=f())
      })
      
      output$xy_Table <- renderTable({
        xyTable
      })
    })

Thanks a lot for any help.


Solution

  • You need to use a reactive xyTable in order for the output to update. Also, append the rows inside an observer rather than a reactive expression, and make sure to save the updated reactive value:

    library(shiny)
    library(tidyverse)
    
    ui <- fluidPage(
      sidebarPanel(
        numericInput("x", "Enter Value of X", 1),
        numericInput("y", "Enter Value of Y", 1),
        actionButton("add_data", "Add Data", width = "100%")
      ),
      mainPanel(
        tableOutput("xy_Table")
      )
    )
    
    server <- function(input, output, session) {
      xyTable <- reactiveVal(
        tibble(x = numeric(), y = numeric())
      )
    
      observeEvent(input$add_data, {
        xyTable() %>%
          add_row(
            x = input$x,
            y = input$y,
          ) %>%
          xyTable()
      })
    
      output$xy_Table <- renderTable(xyTable())
    }
    
    shinyApp(ui, server)