acombo
acombo

Reputation: 61

How to call "stateLoadParams" in Shiny to pass table state to output rendering

I'm really stuck on a related problem (Question:79442948) and I'm trying every possible solution.

One of potential solution is to use stateLoadParams() function to load the state of a DT table on after editing. Unfortunately I'm not able to find any documentation on how to call this from renderDT.

The code bellow don't actually loads the state... but I don't know how to correct it.

Can anyone please help me?

Considerer the_state <- list(st = isolate({input$reg_tbl_state}))

# Render the Data.Table
      output$reg_tbl <- DT::renderDT({ 
        # Render the Table
        DT::datatable(
          loc_dt1(),
          extensions = 'Buttons',
          filter = 'top',
          editable = TRUE,
          escape = FALSE,
          options = list(
            dom = 'Bfrtip',
            pageLength = 5, autoWidth = TRUE,
            lengthChange = FALSE,
            stateLoadParams = the_state$st, # Here Lies the problem
            stateSave = TRUE,
            stateDuration = -1       # Keep state indefinitely
))
            # )
          )
        )},
        server = TRUE
      )
      

Upvotes: 0

Views: 28

Answers (1)

acombo
acombo

Reputation: 61

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.

  • Need to isolate data
  • 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, {
      
      add_row_dt <- mod_df() %>%
         dplyr::bind_rows(
            dplyr::tibble(Height = input$height,
                          Weight = input$weight)
         )
      
      print(add_row_dt)
      
      df_reactive$df <- add_row_dt
      
   })
   
   
   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)

Upvotes: 0

Related Questions