Hi all, eventually managed to solve it myself thanks to the awesome reactlog
package.
In case somebody finds that useful I'm pasting the full solution down bottom and I will describe the fix which in the end proved to be quite simple:
Discovered problem in the previous solution
I failed to notice that when I do table edits on a reactive value it then updates all reactive functions that depend on it. If I then use the same reactive value as the input for printing the table (below), the awesome functionality of DT
of keeping a proxy of that table and displaying it with all filters context etc. won't take place.
output$x1 = renderDT(rec_val$iris, selection = 'none', filter = "top", rownames = F, editable = T)
Discovered solution
In order to be able to use it effectively I had to use both eventReactive
and observeEvent
with reactiveValues
and use a different source for table rendering. As you see below I have the reactive event that pulls the data (e.g. from DB) which then is wrapped in reactive values and observe event so that I could use that object when subsetting the values of the editable table (can't use a reactive expression there). However, table rendering happens only on the reactive event and the reactive value is used only for storing table edits. Thanks to this I can leverage the proxy feature of DT
. Hope somebody will find it useful!
my_event <- eventReactive(input$go, {
x = iris
x$Date = Sys.time() + seq_len(nrow(x))
x <- as.data.frame(x)
})
rec_val <- reactiveValues(df = NULL)
observe({
rec_val$df <- my_event()
})
output$x1 <- renderDT(my_event(), selection = 'none', filter = "top", rownames = F, editable = T)
Full code:
library(shiny)
library(DT)
options(shiny.reactlog = TRUE)
shinyApp(
ui = fluidPage(
actionButton(
inputId = "go",
label = "Update"
),
DTOutput('x1')
),
server = function(input, output, session) {
my_event <- eventReactive(input$go, {
x = iris
x$Date = Sys.time() + seq_len(nrow(x))
x <- as.data.frame(x)
})
rec_val <- reactiveValues(df = NULL)
observe({
rec_val$df <- my_event()
})
output$x1 <- renderDT(my_event(), selection = 'none', filter = "top", rownames = F, editable = T)
proxy <- dataTableProxy('x1')
observeEvent(input$x1_cell_edit, {
info = input$x1_cell_edit
str(info)
i = info$row
j = info$col + 1 # column index offset by 1
v = info$value
rec_val$df[i, j] <<- DT::coerceValue(v, rec_val$df[i, j])
replaceData(proxy, rec_val$df, resetPaging = FALSE, rownames = FALSE)
})
}
)