excelR icon indicating copy to clipboard operation
excelR copied to clipboard

Editing and Resetting Tables

Open rb543210 opened this issue 3 years ago • 4 comments

I am trying to use excelR for editable tables that can be reset by a button. The code below is a simplified extract from a larger app. I see two issues when I do this, although one might be a feature request:

  1. When editing a cell once and then discarding, the table behaves as expected. I can make as many different edits as I want and get the expected result, but when I edit the same cell twice in the same way, the second edit (and subsequent edits) do not show up as changed. E.g., if you make the value of A1 5 and reset, and then make A1 5 again, the change is not registered.

  2. There doesn't seem to be a way to extract the value of input$data without editing the table. I.e., if I remove the line rvals$changes <- FALSE, the button is always shown and the value of rvals$changes is always TRUE after the first edit, even though the table shows the reset values. In this simplified example it doesn't matter, but in a larger context it makes excelR much harder to use.

Code used to generate bug

library(shiny)
library(excelR)
library(compare)

edit_table_ui <- function(id, title) {
    ns <- NS(id)
    div(
        textOutput(ns("edits")),
        excelOutput(ns("data")),
        conditionalPanel(
            condition = "output.edits == 'TRUE'",
            ns=ns,
            br(),
            shiny::actionButton(ns("discard"), "Discard Changes")
        )
    )
}

edit_table_server <- function(id, df, changes, baseline) {
    moduleServer(id, function(input, output, session) {
        rvals <- reactiveValues(data = isolate(df()), changes = isolate(changes()))
        
        observe({
            rvals$data <- df()
        })
        
        # Check whether changes were made to table
        observeEvent(input$data, {
            rvals$data <- excel_to_R(input$data)
            rvals$changes <- !isTRUE(compare(baseline, rvals$data, ignoreNames = TRUE))
        })
        
        # Render table as rhandsontable
        output$data <- renderExcel(excelTable(rvals$data))
        
        # Discard changes and reset table
        observeEvent(input$discard, {
            rvals$data <- baseline
            rvals$changes <- FALSE
        })
        
        output$edits <- renderText(rvals$changes)
        outputOptions(output, "edits", suspendWhenHidden = FALSE)
    })
}

app_data <- head(iris)

shinyApp(
    ui = fluidPage(excelOutput("table"), textOutput('c'), edit_table_ui("tbl2", "excelR")),
    server = function(input, output, session) {
        r <- reactiveValues(data = app_data, changes = FALSE)
        edit_table_server("tbl2", reactive(r$data), reactive(r$changes), app_data)
    }
)

rb543210 avatar Sep 03 '21 22:09 rb543210

@rb543210 Which version of excelR are you using? The first issue is not replicable in the latest development version of excelR. The second issue is more of a feature request which I plan to implement in the next version of excelR.

Swechhya avatar Sep 08 '21 07:09 Swechhya

@Swechhya Thanks for your response! I'm using excelR 0.4.0 and R 4.0.2.

rb543210 avatar Sep 09 '21 23:09 rb543210

@rb543210 Can you try with the development version? I'll be releasing a new version with the fixes and getting the data soon.

Swechhya avatar Oct 02 '21 11:10 Swechhya

@Swechhya It looks like both issues I identified are fixed. Thank you for the package! It seems like the next version will be really useful.

rb543210 avatar Nov 30 '21 21:11 rb543210