0

I have created an application using reactiveValues to populate the datatable similar to the response here R Shiny DT - edit values in table with reactive

What I cannot seem to figure out is after editing the table it resets to the first page. This does not happen when the datatable is not created from a reactiveValues table.

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    DTOutput('x1'),
    verbatimTextOutput("print")
  ),
  server = function(input, output, session) {
    x = reactiveValues(df = NULL)

    observe({
      df <- iris
      df$Date = Sys.time() + seq_len(nrow(df))
      x$df <- df
    })

    output$x1 = renderDT(x$df, selection = 'none', editable = TRUE)

    proxy = dataTableProxy('x1')

    observeEvent(input$x1_cell_edit, {
      info = input$x1_cell_edit
      str(info)
      i = info$row
      j = info$col
      v = info$value

      x$df[i, j] <- isolate(DT::coerceValue(v, x$df[i, j]))
     replaceData(proxy, x(), resetPaging = FALSE)  # important I have tried with and without this line no impact on page resetting
    })

    output$print <- renderPrint({
      x$df
    })
  }
)

I wanted to share that I figured out how to solve this, still a little confused as to why it was so complicated but if anyone else has the same issue.

  x = reactiveValues(df = NULL)
  x$df2 = NULL
  #Tells which data to pull based on how the OSC list is populated  
  FundData <- observe({
    if(input$SelectFunds == 'None Selected'){
      x$df <- head(QDataAnalystSummary,0)
    }else if(input$SelectFunds == 'Load OSC List'){
      tmp_funds <- subset(QDataAnalystSummary,as.character(QDataAnalystSummary$OSC) %in% as.character(OSCData()$OSC))
      tmp_funds <- subset(tmp_funds,tmp_funds$`Quarter End` == CurrentQtr)
      tmp_funds_new <- NULL
      for(i in 1:nrow(OSCData())){
        tmp_fd <- subset(tmp_funds,tmp_funds$OSC == OSCData()$OSC[i])
        tmp_funds_new <- rbind(tmp_funds_new,tmp_fd)
      }
      tmp_funds_new
      x$df <- tmp_funds_new
      x$df2 <- tmp_funds_new
    }
    else if(input$SelectFunds == 'Search By Analyst'){
      tmp_funds5 <- subset(QDataAnalystSummary,QDataAnalystSummary$Analyst %in% input$Analyst)
      tmp_funds5 <-  subset(tmp_funds5,tmp_funds5$`Quarter End` == CurrentQtr)
      x$df <- tmp_funds5
    })
 #Summary Table showing general fund info and current quarter stats for IC Meeting Funds 
  output$summary_ic <-  DT::renderDT({
    QDAW <- subset(QDataAnalystSummary,QDataAnalystSummary$OSC %in% OSCData()$OSC & QDataAnalystSummary$`Quarter End` ==CurrentQtr)
    if(nrow(QDAW) >= 1){
      QDAW$Notes <- ''
      QDAW_new <- NULL
      for(i in 1:nrow(OSCData())){
        tmp_fd <- subset(QDAW,QDAW$OSC == OSCData()$OSC[i])
        QDAW_new <- rbind(QDAW_new,tmp_fd)
      }
      QDAW <- QDAW_new
    }

    datatable(QDAW,
              rownames = FALSE,caption = "Current Quarter Data",
              filter = "top",extensions = c('Buttons','ColReorder'),editable = list(target = 'cell',disable = list(columns=c(0:9))),
              options = list(initComplete = JS(
                "function(settings, json) {",
                "$(this.api().table().header()).css({'background-color':'rgb(85,114,138)','color': '#fff'});","}"),
                autoWidth = TRUE,
                columnDefs = list(list(width = '2%', targets = list(0,1,6,7,8,9)),
                                  # list(width = '20%', targets = list()),
                                  list(className = 'dt-center',targets = c(1,5,6,7,8,9)),
                                  list(visible = FALSE, targets = c(0,5,8,9))
                )
                ,resetPaging = FALSE,
                bFilter = 1,bSortClasses = 1,

                aLengthMenu = list(c(10,20,50, -1), list('10','20','50','All')),iDisplayLength = 10,
                searchHighlight = TRUE,
                dom = 'Blfrtip',buttons = c('colvis','excel','copy'),colReorder= TRUE,
                scrollX = TRUE,
                # scrollY = "1000px",
                fixedHeader = TRUE,
                paging=TRUE,server = TRUE))%>%
                    formatRound('Trailing Average', 2) %>%
                    formatStyle('Trailing Average',
                  color = 'white',
                  background = styleInterval(c(50,75),c('green','orange','red'))) %>%
                formatCurrency('AUM')
              })



  proxy = dataTableProxy('summary_ic')

  observeEvent(input$summary_ic_cell_edit, {
    info = input$summary_ic_cell_edit
    str(info)
    i = info$row
    j = info$col + 1  # column index offset by 1
    v = info$value

    x$df2[i, j] <<- isolate(DT::coerceValue(v, x$df2[i, j]))
    replaceData(proxy, x$df2, resetPaging = FALSE, rownames = FALSE)
  })
Aaron H
  • 1
  • 1
  • My actual data has up to 500 rows so I have hard coded page view to 25, if someone updates a column in the data on page 10 I want to prevent them from going back to the first page. – Aaron H Oct 24 '19 at 19:56
  • Your `renderDT` is dependent of `x`. So, whenever `x` changes, the `renderDT` reacts and the datatable is re-rendered. That explains the jump to the first page. Do you really need a reactive dataframe in `renderDT`? – Stéphane Laurent Oct 26 '19 at 10:43
  • 1
    Thanks for the help, I was able to figure it out by no longer keeping the reactive portion in the renderDT. – Aaron H Oct 28 '19 at 14:24

0 Answers0