rhandsontable on multiple tables from SQlite database

338 Views Asked by At

Assistance will be greatly appreciated.

I am working on a shiny app which involves the use of both multiple SQlite databases and rhandsontable package. I found alot of helpful material online with respect to using this package but I am at a level of frustration as I spend 2 days stuck on one problem which I think its worth asking.

So the script below depicts the server and the UI of the rhandsontable. I wanted to be able to enable the user edit, and safe their modified table (which is covered alot online) but across multiple tables (something I am struggling with)

What my code does is that it opens the 1st table, and yes If i make a modification it does safe. But when I attempt to go to another table through the select input, the other table content immediately gets REPLACED by the initial modified one.

I really would like the modifications to be independent without affecting other tables.

Again, assistance will be greatly appreciated.

downloadTableUI <-  function(id) {
  ns <- NS(id)
  tagList(
    sidebarLayout(
      sidebarPanel( 
        selectInput(ns("dataset"), "Choose a dataset:",
          choices = dput(as.character(alltables[1: NROW(alltables)]))),
        radioButtons(ns("filetype"), "File type:",
          choices = c("csv", "tsv")),
        dateRangeInput(ns("daterange2"), "Date Filtration",
          start = "2017-02-17",
          end = "2017-03-07"),
        actionButton(ns("saveBtn"), "Save"),
        br(),
        downloadButton(ns('downloadData'), 'Download File', class = "btn-info")
      ),
      mainPanel(
        rHandsontableOutput(ns('tabletest'), width = 730, height = 600)
      ),
      position = c("left")
    )
  )
}

DownloadTable <-  function(input, output, session, pool) {
#select databases
  tableChoozer <- reactive({input$dataset})
  # dateSelector <- reactive({input$daterange2})

  # Initiate the reactive table
  p1 <- reactive({
    results <- dbGetQuery(pool, paste('select * from ', tableChoozer()))
    return (results) 
  })

  Mychanges <- reactive({

    observe({
    input$saveBtn# update database file each time the button is pressed
    if (!is.null(input$tabletest)) {#if there 's a table input
      dbWriteTable(pool, tableChoozer(),hot_to_r(input$tabletest), overwrite = TRUE, row.names = FALSE)# overwrite the database
    }
  })
#THIS IS WHERE I THINK THE PROBLEM IS
    if (is.null(input$tabletest)) {
      return (p1())
    } else if (!identical(p1(), input$tabletest)) {
      mytable <- as.data.frame(hot_to_r(input$tabletest))
      return (mytable)
    }
  })


output$tabletest <- renderRHandsontable({
    rhandsontable(Mychanges()) %>%
    hot_cols(columnSorting = TRUE, highlightCol = TRUE, highlightRow = TRUE,allowRowEdit = FALSE, allowColEdit = FALSE, exportToCsv = TRUE)
  })


  output$downloadData <- downloadHandler(
    filename = function() {
      paste("table.csv")
    },
    content = function(file) {
      sep <- switch (input$filetype, "csv" = ",", "tsv" = "\t")

      write.table(p1(), file, sep = sep, row.names = FALSE)
    }
  )
}
1

There are 1 best solutions below

2
On BEST ANSWER

This code is untested, but hopefully it will work. Put the following at the top level of your server.R file

observeEvent( input$saveBtn, 
  {
    # update database file each time the button is pressed
    if (!is.null(input$tabletest)) {
      #if there 's a table input
      dbWriteTable(pool, tableChoozer(),
        hot_to_r(input$tabletest), overwrite = TRUE, row.names = FALSE)
        # overwrite the database
   },
   ignoreInit = TRUE
)

Using observeEvent rather than observe prevents a reactive dependency on tableChoozer and input$tabletest which seems to be your problem. ignoreInit makes it so the save event is not triggered at the initialization of the savebutton.