Shiny DT, once you edit can you save to the file you opened from

I am opening a csv file in a DataTable using the DT package, I can edit it in my main page, but cannot find a way to save that back to the original file. I can download that edited table but that is cumbersome to navigate back to the folder where my original file is located and overwrite it. I am using the downloadHandler to output the file, is there something similar to save the file?

Is it possible to open a file, edit in the DT output and just save that back to the original file? I am confused if there is a problem with that due the web security and not explicitly being able to write a file without input from the user. Trying to understand if I am just not able to figure out the code or if it is due to security constraint.

Thanks

Hi,

I am not a web developer, but I believe it is pretty much the default of web browser to not allow web pages to write to disk without user action....

That said, and on a very selfish note (sorry about that), I was wondering if you would mind sharing how you manage to feed into an editable DT table data coming from an uploaded file. Do you implement server-side or client-side editing? I am trying to implement server-side editing based upon a data.frame that is contained in a reactive object, but I am stuck with the inability to set a reactiveValues content using a reactive object (see this other thread).

Thanks

My solution was cobbled together from several sources to accomplish what I wanted to do for an assignment. Honestly I pulled from so many sources I cannot remember them all (I probably should have added the links in my comments but when you are just trying to get something to work, I lost track of what I got from where). What I had to do was open the file, allow it to be edited, and then have the user download and overwrite the original file to save it. Like you said, I am still not sure if it is a web security thing (which I think it is) or if I just don't know enough to code the saving of the file. I had a time constraint so my shortcut was just to manually have the user overwrite the original file. I would love to know if you could overwrite with changes. You would think you should be able to...

What I ended up doing was prompting the user to open the file in the UI like this:
fileInput("upload", "Load file to Edit",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
DT::dataTableOutput("x1"),

                     h6("To save your changes use the button below to download and overwrite the file you modified"),
                     downloadButton("download", label = "Save Changes"),

On the server side:
A lot of this was pulled from here -> https://stackoverflow.com/questions/54426548/how-to-edit-a-table-using-dt-and-shiny-from-an-uploaded-file

below is for opening and editing DataTable files

vals <- reactiveValues(x = NULL)

observe({

# input$upload will be NULL initially. After the user selects
# and uploads a file, head of that data file by default,
# or all rows if selected, will be shown.
req(input$upload)

tryCatch(
  {
    x <- read.csv(input$upload$datapath,
                  header = TRUE,
                  sep = ",",
                  stringsAsFactors = TRUE,
                  row.names = NULL)
    
  },
  error = function(e) {
    # return a safeError if a parsing error occurs
    stop(safeError(e))
  }
)
# Reactive values updated from x
vals$x <- x

})

output$x1 = DT::renderDataTable(vals$x, selection = 'none', rownames = FALSE, edit = TRUE,
options = list(pageLength = 15, info = FALSE,
lengthMenu = list(c(15, -1), c("15", "All")),
dom='t',ordering=F))

proxy = dataTableProxy('x1')

observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
i = info$row
j = info$col + 1
v = info$value
# Below is the crucial spot where the reactive value is used where a reactive expression cannot be used
vals$x[i, j] <<- DT:::coerceValue(v, vals$x[i, j])
replaceData(proxy, vals$x, resetPaging = FALSE, rownames = FALSE)
})

output$download <- downloadHandler("Overwrite Original File",
content = function(file){
write.csv(vals$x, file, row.names = F)
},
contentType = "text/csv")
}

Thank for your quick response. vals <- reactiveValues(x = NULL) is the key !!!

Awesome

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.