---
title: "Using downloadableReactTable Shiny Module"
author: "Mohammed Ali"
date: "`r Sys.Date()`"
output: 
    rmarkdown::html_vignette:
        toc: TRUE
        toc_depth: 3
vignette: >
  %\VignetteIndexEntry{Using downloadableReactTable Shiny Module}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

# Overview

## Purpose 
The document explains how to use **downloadableReactTable** shiny module in periscope2 applications.

## Features
* Ability to display and download datasets.
* Table rows selection can be multiple, single or none (the default)
  * When selection mode is enabled an additional column will be added to the table
  * The selection controls will be radio buttons for single row selection and checkboxes for "multiple" rows selection mode
* Returns a reactive expression containing named list with two elements: **selected_rows** and **table_state**
* Supports full-table searching including regular expressions
* Columns are sort-able in both directions
* Configurable table "window" (viewing area) height with infinite vertical 
scrolling (no paging by default)
* Supports rownames 
* Requires minimal code (see the Usage section for details)
* Uses **downloadFile** Shiny Module functionality to ensure consistent
download functionality for table data.
* **downloadFile** button will be hidden if `downloadableReactTable` parameter `download_data_fxns` or
`downloadableReactTableUI` parameter `downloadtypes` is empty

# Usage

## Shiny Module Overview
Shiny modules consist of a pair of functions that modularize, or package, a small piece of reusable functionality.  The UI function is called directly by the user to place the UI in the correct location (as with other shiny UI objects). The module server function that is called only once to set it up using the module name as a function inside the server function (i.e. user-local session scope.  The first function argument is a string that represents the module id (the same id used in module UI function). Additional arguments can be supplied by the user based on the specific shiny module that is called.  There can be additional helper functions that are a part of a shiny module.

The **downloadableReactTable** Shiny Module is a part of the *periscope2* package and 
consists of the following functions:

* **downloadableReactTableUI** - the UI function to place the table in the application
* **downloadableReactTable** - the server function to be called inside server_local.R.

## downloadableReactTableUI

The **downloadableReactTableUI** function is called from the ui.R (or equivalent) 
file in the location where the table should be placed.  This is similar to other
UI element placement in shiny.

The downloadableReactTableUI looks like:

<center><img src="figures/downloadableReactTable-1.png" width="500px"></center>

The downloadableReactTableUI function takes the unique object ID for the UI object.

The next two arguments (downloadtypes and hovertext) are passed to the
downloadFileButton and set the file types the button will allow the user to
request and the downloadFileButton's tooltip text.  


```{r, eval=F}
# Inside ui_body.R or ui_sidebar.R

 downloadableReactTableUI(
             id            = "object_id1",
             downloadtypes = c("csv", "tsv"),
             hovertext     = "Download the data here!")
```

## downloadableReactTable
The **downloadableReactTable** function is called directly. The call consists of the following:

* the unique object ID that was provided to downloadableTableUI when creating the UI object
* the logging logger to be used
* **file_name_root** is an optional character, function or reactive expression providing downloadable file name
* the root (prefix) of the downloaded file name to be used in the browser as a character string or a reactive expression that returns a character string
* **download_data_fxns** named list of functions or reactive expressions that provide the data to the downloadFileButton (see below).  
  * It is important that the types of files to be downloaded are matched to the correct data function in the list.  
  * The function/reactive expression names are unquoted - they will be called at the time the user initiates a download *(see requirements below)*.
  * The download functions or reactive expressions can all be the same or different from each other and/or the one provided to **table_data**.  This allows finer control over what the user can view vs. download if desired.  For example you can allow a user to view a smaller subset of data but download an expanded dataset, or perhaps download a redacted version of data, etc.
* This module also supports most of reactable table options for further customization. See the example below.

**Data Function or Reactive Expression Requirements**

* If a function is provided it must be parameter-less (require NO parameters).  No parameters will be provided when a function is called to retrieve the plot or data.  Reactive expressions cannot take parameters by definition.
* The function or reactive expression must return an appropriate data format for the file type. 
* For instance: csv/tsv/xlsx types require data that is convertible to a tabular type,
to various download types see the downloadFile module help or vignette.
* For the visible table data the return value must be able to be converted to tabular format
* Since the function or reactive expression is called at the time the user requests the data it is 
recommended that reactive expressions are used to provide dynamic values from the application to create the table.

**Reactive Return Value**

* The server function returns a reactive expression containing named list with two elements:
  * **selected_rows**: data.frame of current selected rows. 
  ```
  * Note that this is the data, not references, rownumbers, etc from the table -- it is the actual, visible, table row data.  This allows the developer to use this more easily to update another table, chart, etc. as desired.
  ```
  * **table_state**: a list of the current table state. The list keys are ("page", "pageSize", "pages", "sorted" and "selected")


* It is acceptable to ignore the return value as well if this functionality is not needed.  Simply do not assign the result to a variable.

**Customization Options**

*downloadableReactTable* module can be customized using reactable function arguments(see `?reactable::reactable`). These options can be sent as a named options via the server function, see example below. 

```{r, eval = F}
# Inside server_local.R
 library(shiny)
 library(periscope2)
 library(reactable)

table_state <- downloadableReactTable(
             id                 = "object_id1",
             table_data         = reactiveVal(iris),
             download_data_fxns = list(csv = reactiveVal(iris), tsv = reactiveVal(iris)),
             selection_mode     = "multiple",
             pre_selected_rows  = function() {c(1, 3, 5)},
             table_options      = list(columns = list(
                 Sepal.Length = colDef(name = "Sepal Length"),
                 Sepal.Width  = colDef(filterable = TRUE),
                 Petal.Length = colDef(show = FALSE),
                 Petal.Width  = colDef(defaultSortOrder = "desc")),
                 showSortable = TRUE,
                 theme = reactableTheme(
                     borderColor = "#dfe2e5",
                     stripedColor = "#f6f8fa",
                     highlightColor = "#f0f5f9",
                     cellPadding = "8px 12px")))

        observeEvent(table_state(), { print(table_state()) })

# NOTE: table_state is the reactive return value, captured for later use
```

## Sample Application
For a complete running shiny example application using the downloadableReactTable module you can create and run a *periscope2* sample application using:

```{r, eval=F}
library(periscope2)

app_dir = tempdir()
create_new_application(name = 'mysampleapp', location = app_dir, sample_app = TRUE)
runApp(paste(app_dir, 'mysampleapp', sep = .Platform$file.sep))
```

# Additional Resources


**Vignettes**

* [New Application](new-application.html)
* [downloadFile Module](downloadFile-module.html)
* [downloadablePlot Module](downloadablePlot-module.html)
* [logViewer Module](logViewer-module.html) 
* [applicationReset Module](applicationReset-module.html)
* [announcement Module](announcement-module.html)
* [Announcement Configuration Builder](announcement_addin.html)
* [Theme Configuration Builder](themeBuilder_addin.html)
