Reactive Table: Hiding Observation and Edit in shiny

I'm creating a reactive shiny app, where I have to edit a data frame and save it. But in editing part, first I would like to hide all other observation except for the selected rows. I would like to edit it and again select another observation and edit it and save it again and so on.

I had created a sample data, Here I'm selecting a country and showing only that country observation. I would like to edit the prices column, It should update in overall data and I need to save it. Then later when I'm selecting a country, it will fetch data from edited data. And edit it save it automatically and go on
...

rm(list = ls())


library(shiny)
library(shinydashboard)


#--------------------------------

df <- data.frame("country" =c("Russia", "China", "US", "India", "UK" )
                 , "tv_cost" = c(43, 67, 78, 56, 78 )
                 , "fridge_cost" = c(78, 45, 56, 78, 47)
                 , "microwave" = c(44, 23,31,29, 34)
                 )


#Shiny Dashboard

ui <- dashboardPage(skin = "green"
                    , dashboardHeader(title = "Edit Table")
                    , dashboardSidebar(sidebarMenu(menuItem("Edit Data", tabName = "tab_01" )
                                                   , menuItem("Output", tabName = "tab_02")
                                                   , menuItem("Input", tabName = "tab_03")
                                                   ))
                    , dashboardBody(tabItems(tabItem(tabName = "tab_01"
                                                     , selectInput(inputId = "countryid", label = "SELECT COUNTRY" , choices = df$country )
                                                     , DT::dataTableOutput("table1"))
                                             , tabItem(tabName = "tab_02", DT::dataTableOutput("table2"))
                                             , tabItem(tabName = "tab_03", DT::dataTableOutput("table3"))
                                             ))
                    )#dashboardpage ends here

server <- function(input, output, session){

  #Creating a blank Data frame to update every change 
  df_02 <- reactive(df_03 <-  NULL)


  #Showing Data table, for editing, "I'm filtering data here but I have to hide other observation "
  df_04 <- reactive(df %>% 
                      filter(country == input$countryid )) 


  output$table1 <-  renderDT({df_04()})

  # saving the edit data

  #Observing edited table 

  #updating it edited frame df_02

  #Rendering overall edited df. 
  output$table2 <- renderDT({df_02()})

  #input file
  output$table3 <- renderDT({df})



}

shinyApp(ui, server)

Thanks

Hi @saaz. I have edit the server script and use reactiveValues not reactive. renderDT is not a function which use DT::renderDataTable and all data frame change to DT::datatable which can add the editable option. The edited information will be available as input$ + renderDataTable's output name + _cell_edit. So, we can change the edited data table with the information. The following is the script. Hope they can help.

library(shiny)
library(shinydashboard)


#--------------------------------

df <- data.frame("country" =c("Russia", "China", "US", "India", "UK" )
                 , "tv_cost" = c(43, 67, 78, 56, 78 )
                 , "fridge_cost" = c(78, 45, 56, 78, 47)
                 , "microwave" = c(44, 23,31,29, 34)
)


#Shiny Dashboard

ui <- dashboardPage(skin = "green"
                    , dashboardHeader(title = "Edit Table")
                    , dashboardSidebar(sidebarMenu(menuItem("Edit Data", tabName = "tab_01" )
                                                   , menuItem("Output", tabName = "tab_02")
                                                   , menuItem("Input", tabName = "tab_03")
                    ))
                    , dashboardBody(tabItems(tabItem(tabName = "tab_01"
                                                     , selectInput(inputId = "countryid", label = "SELECT COUNTRY" , choices = df$country )
                                                     , DT::dataTableOutput("table1"))
                                             , tabItem(tabName = "tab_02", DT::dataTableOutput("table2"))
                                             , tabItem(tabName = "tab_03", DT::dataTableOutput("table3"))
                    ))
)#dashboardpage ends here

server <- function(input, output, session){
  vals <- reactiveValues(data = df, edited = df)
  
  output$table1 <-  DT::renderDataTable(DT::datatable(filter(vals$edited, country == input$countryid), editable = TRUE))
  
  observe(
    {
      req(input$table1_cell_edit)
      vals$edited[which(vals$edited$country == input$countryid), input$table1_cell_edit$col] <- input$table1_cell_edit$value
    }
  )
  
  #Rendering overall edited df. 
  output$table2 <- DT::renderDataTable(DT::datatable(vals$edited))
  
  #input file
  output$table3 <- DT::renderDataTable(DT::datatable(vals$data))

}

shinyApp(ui, server)
1 Like

Hi @raytong , First of all thanks. Code runs great.

I was adding save button in edit page, and changing observe to observeevent. Whenever i'm editing two columns of same country, its saving the last edited column only.

Also I'm not able to do this in rhandsontable package instead of DT.

Regards

@raytong Thanks for the example! One note is that if you don't want values to automatically update when the input changes, you should wrap the input in isolate() in the observe function. For example isolate(input$countryid).