0

I am trying to add an editable datatable in r shiny. I have two components to it. First being allowing the user to add a new row and delete a selected row. Secondly when the user changes any value in the cell it should update the corresponding cell. The issue I am facing first off is to unable to delete selected rows. I am able to add those but not delete. Below is the code which I am using. Also I am trying to reset to a default table but it wont reset to the default table. How can I fix this. Thank you.

### Libraries
library(shiny)
library(dplyr)
library(DT)

### Data
input_data <- data.frame(aa = c("Brand1", "Brand2","Brand3"),
                         bb = c(2000, 3000, 4000),
                         cc = c (.5, .5, .5),
                         dd = c(2000, 3000, 4000),
                         ee = c (.5, .5, .5),
                         ff = c (.5, .5, .5),
                         gg = c (.5, .5, .5),
                         stringsAsFactors = FALSE)

### Shiny App
shinyApp(
  ui = basicPage(
    mainPanel(

      actionButton("reset", "Reset"),
      actionButton("add_btn", "Add"),
      actionButton("delete_btn", "Delete"),
      tags$hr(),
      DT::dataTableOutput("mod_table")    )
  ),
  server = function(input, output) {

    #demodata<-input_data

    this_table <- reactiveVal(input_data)

    observeEvent(input$add_btn, {
      t = rbind(data.frame(aa = "default",
                           bb = 1000000,cc = 2.0,dd = 20000, ee = 40,ff = 00 , gg = 00), this_table())
      this_table(t)
    })

    observeEvent(input$delete_btn, {
      t = this_table()
      print(nrow(t))
      if (!is.null(input$shiny_table_rows_selected)) {
        t <- t[-as.numeric(input$shiny_table_rows_selected),]
      }
      this_table(t)
    })
observeEvent(input$reset, {
       this_table <- input_data # your default data
     })

    output$mod_table <- DT::renderDataTable({
      datatable(this_table(), selection = 'single',editable = TRUE, options = list(dom = 't'))

    })
    }
)

1
  • does the answer work for you? Commented Nov 20, 2019 at 20:58

2 Answers 2

1
+50

Deleting rows:

You get the selected rows with input$tableId_rows_selected. Your tableId is mod_table.

So, if you change from input$shiny_table_rows_selected to input$mod_table_rows_selected it will work.

Resetting table:

If you switch from assigning to this_table to using this_table() as a "set function" it will work. I think its just a small typo as you already use this syntax for the "delete part" correctly:

observeEvent(input$reset, {
  this_table(input_data)
})

Reproducible code:

library(shiny)
library(dplyr)
library(DT)

### Data
input_data <- data.frame(aa = c("Brand1", "Brand2","Brand3"),
                         bb = c(2000, 3000, 4000),
                         cc = c (.5, .5, .5),
                         dd = c(2000, 3000, 4000),
                         ee = c (.5, .5, .5),
                         ff = c (.5, .5, .5),
                         gg = c (.5, .5, .5),
                         stringsAsFactors = FALSE)

### Shiny App
shinyApp(
  ui = basicPage(
    mainPanel(

      actionButton("reset", "Reset"),
      actionButton("add_btn", "Add"),
      actionButton("delete_btn", "Delete"),
      tags$hr(),
      DT::dataTableOutput("mod_table")    )
  ),
  server = function(input, output) {

    #demodata<-input_data

    this_table <- reactiveVal(input_data)

    observeEvent(input$add_btn, {
      t = rbind(data.frame(aa = "default", bb = 1000000,cc = 2.0, dd = 20000, 
                           ee = 40,ff = 00 , gg = 00), this_table())
      this_table(t)
    })

    observeEvent(input$delete_btn, {
      t = this_table()
      print(input$mod_table_rows_selected)
      if (!is.null(input$mod_table_rows_selected)) {
        t <- t[-input$mod_table_rows_selected,]
      }
      this_table(t)
    })

    observeEvent(input$reset, {
      this_table(input_data)
    })

    output$mod_table <- DT::renderDataTable({
      datatable(this_table(), selection = 'single',editable = TRUE, 
                options = list(dom = 't'))
    })
  }
)
Sign up to request clarification or add additional context in comments.

Comments

0

A JavaScript solution:

library(shiny)
library(DT)

### Data
input_data <- data.frame(aa = c("Brand1", "Brand2","Brand3"),
                         bb = c(2000, 3000, 4000),
                         cc = c (.5, .5, .5),
                         dd = c(2000, 3000, 4000),
                         ee = c (.5, .5, .5),
                         ff = c (.5, .5, .5),
                         gg = c (.5, .5, .5),
                         stringsAsFactors = FALSE)

### Callback
callback <- c(
  '$("#add_btn").on("click", function(){',
  '  var newrow = ["default", 1000000, 2, 20000, 40, 0, 0];',
  '  table.row.add(newrow).draw();',
  '});',
  '$("#delete_btn").on("click", function(){',
  '  var rows = table.rows(".selected");',
  '  rows.remove().draw();',
  '});'
)

### Shiny App
shinyApp(
  ui = basicPage(
    mainPanel(
      br(),
      actionButton("reset", "Reset"),
      actionButton("add_btn", "Add"),
      actionButton("delete_btn", "Delete"),
      tags$hr(),
      DTOutput("mod_table")
    )
  ),

  server = function(input, output) {

    output$mod_table <- renderDT({
      input$reset
      datatable(input_data, selection = 'single', editable = TRUE, 
                rownames = FALSE, 
                options = list(dom = 't'), callback = JS(callback))
    }, server = FALSE)

  }
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.