简体   繁体   中英

delete a record from datatable based on the value of textInput Box

How can I delete a record with an action button? The delete action button executes the command properly if I hardcode what I want deleted but it gets grayed out if I want to delete dynamically by pointing at the "delete2" textInput box. For example, if I want to delete a record in the testing table that has a value of 100, I want to type the 100 value in the "delete2" box and when the action button is clicked, it will execute the command and delete the record.

Currently, the button works when I type the 100 value on my delete statement but it doesn't refresh the table until the next time I open the app. To summarize, assume that I want to delete a record from "value1" of 100, How can I delete it dynamically and refresh the datatable? Hope is clear. Below is what I tried:

library(shiny)
library(RSQLite)

ui = fluidPage(
    shinyUI(fluidPage(
      titlePanel("Enter Data into SQLite"),
      sidebarLayout(
        sidebarPanel(
    textInput("value1", label = "Value 1"),
    textInput("value2", label = "Value 2"),
    
    dateInput("SampleDate", label = "Today",value = ""),  
    actionButton("action", label = "Write to DB"),
    actionButton("delete", label = "Delete Records"),
    textInput("delete2", label = "delete these records"),#type record number to be deleted
    
        ),
    mainPanel(
      dataTableOutput("table")
  )
      )
    )))
  
  server = function(input, output,session){
    session$onSessionEnded(function() {
      stopApp()
    }) 
    
    data <- eventReactive(input$action, {
      con <- dbConnect(SQLite(), dbname="sample.sqlite",extended_types=TRUE) 
     dbWriteTable(con, "testing", data.frame(value1 = input$value1, value2 = input$value2, 
                          SampleDate = input$SampleDate, stringsAsFactors = FALSE), append = TRUE)
      
      data <- dbReadTable(con, "testing")
      dbDisconnect(con)
      #Clear form fields to enter more data
      updateTextInput(session, "value1", "value 1", value="")
      updateTextInput(session, "value2", "value 2", value="")
      updateDateInput(session = session, inputId = "SampleDate", value = NA)  
      return(data)
    })
    
  output$table <- renderDataTable(data())

   #Everything above works as expected but the code below to delete the record is not working   
  
   observeEvent(input$delete, {
    con <- dbConnect(SQLite(), dbname="sample.sqlite",extended_types=TRUE) 
    dbExecute(con,"DELETE from testing WHERE value1 = input$delete2") 
    dbDisconnect(con)
  })
  output$table <- renderDataTable(data()) #datatable is not refreshing
  
    
  } 
  shinyApp(ui = ui, server = server)

One option to achieve your desired result would be to move the "reading" part of your eventReactive into an reactive which make reactive to both input$action and input$delete , ie it gets updated if either button is clicked. After doing so you could replace the eventReactive by an observeEvent which now just performs the writing part.

Additionally I made two adjustments. First, I made your example reproducible by adding the code to create a sample database. Second, it's not best practice to connect and disconnect from the database for one action. Instead I use the pool package which connects to the database once when the app is started and disconnects when finished. Third, I use today's Date as the default value for the DateInput as using "" will throw a warning.

library(shiny)
library(RSQLite)
library(DBI)

pool <- pool::dbPool(RSQLite::SQLite(), dbname = "sample.sqlite", extended_types = TRUE)

# Create sql lite df
sample_df <- data.frame(
  value1 = numeric(),
  value2 = numeric(),
  SampleDate = as.Date(x = integer(0), origin = "1970-01-01")
)

# Create responses table in sql database
dbWriteTable(pool, "sample_df", sample_df, overwrite = FALSE, append = TRUE)

ui <- fluidPage(
  shinyUI(fluidPage(
    titlePanel("Enter Data into SQLite"),
    sidebarLayout(
      sidebarPanel(
        textInput("value1", label = "Value 1"),
        textInput("value2", label = "Value 2"),
        dateInput("SampleDate", label = "Today", value = Sys.Date()),
        actionButton("action", label = "Write to DB"),
        actionButton("delete", label = "Delete Records"),
        textInput("delete2", label = "delete these records"), # type record number to be deleted
      ),
      mainPanel(
        dataTableOutput("table")
      )
    )
  ))
)

server <- function(input, output, session) {
  session$onSessionEnded(function() {
    stopApp()
  })

  data <- reactive({
    input$action
    input$delete

    dbReadTable(pool, "testing")
  })

  observeEvent(input$action, {
    dbWriteTable(pool, "testing", data.frame(
      value1 = input$value1, value2 = input$value2,
      SampleDate = as.Date(input$SampleDate), stringsAsFactors = FALSE
    ), append = TRUE)

    updateTextInput(session, "value1", "value 1", value = "")
    updateTextInput(session, "value2", "value 2", value = "")
    updateDateInput(session = session, inputId = "SampleDate", value = Sys.Date())
  })

  observeEvent(input$delete, {
    dbExecute(pool, paste("DELETE from testing WHERE value1 = ", input$delete2))
    
    updateTextInput(session, "delete2", value = "")
  })

  output$table <- renderDataTable(data())
}

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM