Editing multiple cells in a datatable in shiny

旧巷老猫 提交于 2020-01-05 04:15:06

问题


I asked this question earlier - Write editable shiny Datatable to .csv file Trying to edit cells in a shiny datatable and replace the original data with the edited data.

I was able to figure out how to edit a single cell in the datatable, however if multiple cells are edited only the last edit is saved.

Code:

library(shiny)
library(shinydashboard)
library(tidyverse)
library(DT)


users <- reactiveFileReader(
  intervalMillis = 1000,  
  NULL,
  filePath = 'appData/userTest.csv',
  readFunc = read.csv,
  stringsAsFactors = FALSE
)

header <- dashboardHeader(title = "demo")
sidebar <- dashboardSidebar(uiOutput('sidebar'))
body <- dashboardBody(uiOutput("body"))

f1 <- fluidRow(
  box(
    dataTableOutput('userTable'),
    width = 6
  )
)

ui <- dashboardPage(title = 'admin function test', header, sidebar, body, skin='blue')

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

  output$body <- renderUI({
    tabItems(
      tabItem(
        tabName = 'admin', class = 'active', h2(f1)
      )
    )
  })

  output$sidebar <- renderUI({
    sidebarMenu(id = 'sidebarmenu',
                menuItem("admin", tabName = "admin", icon = icon("adjust")),
                actionButton("do", 'save', icon = icon('redo'))
    )
  })

  observeEvent(
    input$do,{
      write.csv(edited(),'appData/userTest.csv', row.names = FALSE)
    })

  output$userTable <- renderDataTable({
    DT::datatable(users(),
                  editable = TRUE,
                  rownames = FALSE)
  })

  edited <- reactive({editData(users(), input$userTable_cell_edit, proxy = NULL, rownames = FALSE, resetPaging = FALSE)})
}

shinyApp(ui = ui, server = server)

Data:

   userName      start        end
1      John 06/08/2019 01/10/2019
2      Mary 01/01/2019 01/10/2019
3      Mike 23/10/2019 01/10/2019
4     Steve 25/07/2019 07/02/2015
5      Kate 01/01/2019 29/04/2019

I imagine this is because the editData() function records only a single edit at a time. How can multiple cells be edited and saved in one go?


回答1:


See below, this will allow multiple changes and each one is tracked.

library(shiny)
library(shinydashboard)
library(tidyverse)
library(DT)

header <- dashboardHeader(title = "demo")
sidebar <- dashboardSidebar(
  sidebarMenu(id = 'sidebarmenu',
              menuItem("admin", tabName = "admin", icon = icon("adjust")),
              downloadButton("downloadResults","Download Results")
  )
)

body <- dashboardBody(
  tabItems(
    tabItem(
      tabName = 'admin', class = 'active', 
        fluidRow(
          box(
            dataTableOutput('userTable'), width = 6
          )
        )
    )
  )
)


ui <- dashboardPage(title = 'admin function test', header, sidebar, body, skin='blue')

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

  dat <- data.frame(userName = c("John","Mary","Mike"), start = c("06/08/2019","01/01/2019","23/10/2019"), stringsAsFactors = FALSE)

  output$userTable <- renderDataTable({
    DT::datatable(isolate(dat),
                  editable = TRUE,
                  rownames = FALSE)
  })

  ###Tracking Changes###
  rvs <- reactiveValues(
    data = NA #dynamic data object
  )

  observe({
    rvs$data <- dat
  })

  proxy = dataTableProxy('userTable')
  observe({
    DT::replaceData(proxy, rvs$data, rownames = FALSE, resetPaging = FALSE)
  })

  observeEvent(input$userTable_cell_edit, {
    rvs$data <<- editData(rvs$data, input$userTable_cell_edit, rownames = FALSE)
  })

  # observeEvent(
  #   input$do,{
  #     write.csv(rvs$data,'userTest.csv', row.names = FALSE)
  #   })

  output$downloadResults <- downloadHandler(
    filename = function(){paste("userTest.csv.csv", sep = "")},
    content = function(file){write.csv(rvs$data, file, row.names = FALSE)}
  )

}

shinyApp(ui = ui, server = server)

If you want multiple cells to be editable at the same time, add this line to your datatable:

editable = list(target = "all") #can be all, row, or column

Few tips when posting in the future:

  1. Create a reproducible example, having it pull data/save data from a file on your computer can't be reproduced
  2. Keep the code simple as possible to focus on your issue. Throwing renderUI's for the body and sidebar just clutters your code.


来源:https://stackoverflow.com/questions/58595096/editing-multiple-cells-in-a-datatable-in-shiny

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!