Finally managed to grasp a solution. For reference let me summarise:
I needed an app that shares a common Editable dataset between multiple session.
When a user (session) edits a cell that value must reflects on other sessions.
Each user should make his own selections/filtering/ordering... and, despite eventual others change the values the current settings (selection...) do not change.
(This is a "basic" problem of concurrent editing of a table)
Bellow is a MWE (actually tailored for my needs) that was based on this article R Shiny and DataTable (DT) Proxy Demonstration
On the code it is commented the two aspects that were messing with a proper operation.
rownames
on replaceData
... I actually read many lines alerting on this... but still...library(shiny)
library(tidyverse)
library(DT)
df <- dplyr::tibble(Height = c("185", "162"), Weight = c("95", "56"))
df_reactive <- reactiveValues(df = df)
ui <- fluidPage(
# App title ----
titlePanel("DT + Proxy + Replace Data"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
shiny::textInput(inputId = "height", label = "height"),
shiny::textInput(inputId = "weight", label = "weight"),
shiny::actionButton(inputId = "add", label = "Add"),
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
DT::DTOutput(outputId = "table")
)
)
)
# Define server logic required to draw a histogram ----
server <- function(input, output, session) {
mod_df <- shiny::reactive(df_reactive$df)
output$table <- DT::renderDT({
DT::datatable(
isolate(mod_df()), # This work Fine
# mod_df(), # This Reflects changes troughout ALL session (the desired behaviour)
# BUT... when value change... filters and ordering is cleared (in all sessions)
extensions = 'Buttons',
filter = 'top',
editable = T,
escape = FALSE,
options = list(
# dom = 'Bfrtip',
dom = 'Bfrtip',
pageLength = 5, autoWidth = TRUE,
lengthChange = FALSE)
)
}, server = T)
shiny::observe({
shiny::updateSelectInput(session, inputId = "remove_row",
choices = 1:nrow(mod_df()))
})
shiny::observeEvent(input$add, {
mod_df(mod_df(x) %>%
dplyr::bind_rows(
dplyr::tibble(Height = input$height,
Weight = input$weight)
))
})
proxy <- DT::dataTableProxy('table')
shiny::observe({
DT::replaceData(proxy, mod_df(),
rownames = TRUE, # IF FALSE Does not work.
resetPaging = FALSE
)
})
shiny::observe({
info = input$table_cell_edit
# str(info)
i = info$row
j = info$col
k = info$value
print(info)
print(mod_df())
loc <- mod_df()
loc[[i, j]] <- k
df_reactive$df <<- loc
})%>%
bindEvent(input$table_cell_edit)
}
shinyApp(ui, server)