/DTedit

Editable DataTables for shiny apps

Primary LanguageR

Travis build status Codecov test coverage

Editable DataTables for shiny apps.

Author: Jason Bryer, Ph.D. Email: jason@bryer.org

Author: David Fong, FRACGP Email: vkelim@bigpond.com

Use the devtools package to install the development version of DTedit:

devtools::install_github('jbryer/DTedit')

To install a release branch, e.g. 2.3.0, of `DavidPatShuiFong/DTedit' :

devtools::install_github('DavidPatShuiFong/DTedit@2.3.0')

The dtedit_demo will run a sample shiny app with to editable data tables.

DTedit::dtedit_demo()

DTedit Screen Shot

Getting Started with DTedit

You can download a simple shiny app using DTedit here: inst/template/app.R

There are three steps to using DTedit in your shiny application.

  1. Define callback function for inserting, updating, and deleting data.
my.insert.callback <- function(data, row) {
  # 'data' contains the dataframe *after* the row has been inserted/added
  # 'row' is the row number where data has been inserted
  mydata <<- rbind(mydata, data[row,])
  # in this case, 'mydata' should just be the same as 'data'
  return(mydata)
}

my.update.callback <- function(data, olddata, row) {
  # 'data' contains the dataframe *after* the row has been updated
  # 'row' is the row number where data has been updated
  # 'olddata' is the previous version of the data
  mydata[row,] <<- data[row,]
  # in this case, 'mydata' should just be the same as 'data'
  return(mydata)
}

my.delete.callback <- function(data, row) {
  # 'data' contains the dataframe *before* the row has been deleted
  # 'row' is the row number where data is to be deleted
  mydata <<- mydata[-row,]
  # in this case, 'mydata' should just be the same as data[-c(row),]
  return(mydata)
}

Typically these functions would interact with a database. As written here, the data would be lost between shiny sessions.

While olddata will contain values as contained in the original data.frame, the values returned in data are limited to values that can be returned by the shiny widgets underlying the input.types. For example, the textInput can return an empty string, but cannot return NA.

  1. Create the dtedit object within your server function.
DTedit::dtedit(
  input, output,
  name = 'mycontacts',
  thedata = mydata,
  edit.cols = c('name', 'email', 'useR', 'notes'),
  edit.label.cols = c('Name', 'Email Address', 'Are they an R user?', 'Additional notes'),
  input.types = c(notes='textAreaInput'),
  view.cols = c('name', 'email', 'useR'),
  callback.update = my.update.callback,
  callback.insert = my.insert.callback,
  callback.delete = my.delete.callback
  )

The input and output are passed from the server function. The name parameter will define the name of the object available to the uiOutput. The thedata is a data.frame for the initial view of the data table. This can be an empty (i.e. no rows) data.frame. The structure of the data.frame will define the inputs (e.g. factors will be drop down, Date will use dateInput, numerics will use numericInput, etc.). There are many other parameters to custom the behavior of dtedit, see ?dtedit for the full list.

  1. Use uiOutput in your UI to display the editable data table.

The name you will pass to uiOutput is the name you passed to the dtedit created on the server side.

uiOutput('mycontacts')

dteditmod (modularized version of dtedit)

You can download a simple modularized shiny app using DTedit here: inst/template/app_mod.R

There are three steps to using DTedit in your modularized shiny application.

  1. Define callback functions, as for dtedit.

  2. callModule in the server function, with dteditmod as the shiny module server function.

return_values <- callModule(
  DTedit::dteditmod,
  id = 'mycontacts',
  thedata = mydata,
  edit.cols = c('name', 'email', 'useR', 'notes'),
  edit.label.cols = c('Name', 'Email Address', 'Are they an R user?', 'Additional notes'),
  input.types = c(notes='textAreaInput'),
  view.cols = c('name', 'email', 'useR'),
  callback.update = my.update.callback,
  callback.insert = my.insert.callback,
  callback.delete = my.delete.callback
  )

The id parameter will define the name of the object available to the dteditmodUI. thedata is a data.frame for the initial view of the data table. This can be an empty (i.e. no rows) data.frame.

  1. Use DTedit::dteditmodUI in your UI to display the editable data table.

The id you will pass to dteditmodUI is the id you passed to the callModule created on the server side.

ns <- shiny::NS(id)
...
dteditmodUI(ns('mycontacts'))

Vignette

See vignette with browseVignettes("DTedit") or on RPubs.

More examples

A very simple example : inst/examples/example.R.
This example can be seen with example("dtedit")

Example with two datatables : inst/shiny_demo/app.R.
This demonstration can be seen with DTedit::dtedit_demo().
This, and other demonstrations, can be called with shinyAppDir arguments.
e.g. DTedit::dtedit_demo(options = list(display.mode = "showcase"))
Note that all .R files in the shiny_demo directory are displayed in showcase mode, not just the .R file used in the actual demonstration!

Example with reactive dataframe : inst/examples/reactivedataframe/app.R.
This demonstration can be seen with DTedit::dtedit_reactive_demo()

Example with reactive input choices : inst/examples/selectInputReactive/app.R.
This demonstration can be seen with DTedit::dtedit_selectInputReactive_demo()

A very simple modularized example : inst/examples/example_mod.R.
A slightly modified version of this example can be seen with DTedit::dtedit_test("simple_modular").

A modularized example with reactive dataframes : inst/examples/reactivedataframe_modular/app.R.
This example can be seen with example("dteditmodUI")

A modularized version with multiple datatables and reactive input choices : inst/shiny_demo/app_mod.R.
This demonstration can be seen with DTedit::dteditmod_demo()

A modularized version with fileInput, binary blobs and action buttons : inst/examples/fileinput_modular/app.R.
This demonstration can be seen with DTedit::dteditmod_fileInput_demo()