# Matrix Input for Shiny

[![R-CMD-check](https://github.com/INWTlab/shinyMatrix/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/INWTlab/shinyMatrix/actions/workflows/R-CMD-check.yaml)
[![Coverage Status](https://img.shields.io/codecov/c/github/INWTlab/shinyMatrix/master.svg)](https://app.codecov.io/github/INWTlab/shinyMatrix?branch=master)
[![CRAN status](https://www.r-pkg.org/badges/version/shinyMatrix)](https://cran.r-project.org/package=shinyMatrix)

# Matrix Input for Shiny

This package provides an input field to enter matrix conveniently in a shiny application. It supports tabbing and jumping linewise in the matrix.

![Screenshot Simple Matrix](https://github.com/INWTlab/shinyMatrix/raw/master/screenshot1.png)

## Installation
From CRAN:
```r
install.packages("shinyMatrix")
```
From GitHub:

```r
if (require("devtools")) install_github("INWTlab/shinyMatrix")
```

## Usage

### UI

The input field is generated by the function `matrixInput`

```r
matrixInput <- function(inputId,
                        value = matrix("", 1, 1),
                        inputClass = "",
                        rows = list(),
                        cols = list(),
                        class = "character"
                        pagination = FALSE,
                        lazy = FALSE){
  [...]
}
```
You can define parameters as follows:

| Parameter | Description |
|-|-|
| `inputId` | `id` of html element |
| `value` | matrix |
| `inputClass` | `class` of html element (Class `matrix-input` is added automatically) |
| `rows` | `list` of parameters (see below) |
| `cols` | `list` of parameters (see below) |
| `class` | class of resulting matrix (`numeric` and `character`) is supported |
| `pagination` | Should the matrix be paginated (10 rows per page) |
| `lazy` | Lazy update data on server |

Parameter `rows` / `cols` take a list of arguments. The following is supported

| Parameter | Description |
|-|-|
|`n`| number of rows (is calculated from `value` per default) |
|`names`| show row/colnames (names are taken from `value`)|
|`editableNames`| should row/colnames be editable? |
| `extend`| should rows/cols be automatically be added if table is filled to the last row / column? |
| `delta` | how many blank rows/cols should be added 
| `multiheader` | Display multiheader - currently only header spanning two columns are supported

Call the matrixInput function in your UI generating, e.g. ui.R

```r
## numeric matrix
matrixInput("matrix1", class = "numeric")

## editable rownames
matrixInput("matrix2",
  rows = list(
    names = TRUE,
    editableNames = TRUE),
  data = matrix(letters[1:12], 3, 4)
)
```
### Get value

You can access the value from the matrix input using `input$inputId` in your server function. The result will always be a matrix of the class defined in `matrixInput`.


### Update Input Field

You can update the input field using `updateMatrixInput`

```r
updateMatrixInput(session, inputId, value = NULL)
```

`value` is the data object. In the future there should be also support to update the other parameters.

## Example Apps

You find the code for the example app in `inst/appXXX`.

### Basic functionality

- Fixed matrix width
- Editable matrix content
- No column and rownames

Use the matrix on the left to input values, matrix on the right displays the result.

```r
library(shinyMatrix)

startApplication("app")
```

### Update Matrix Input from R

- Generate a random matrix within the shiny server function by clicking on "Update Matrix"
- The matrixInput field gets updated with `updateMatrixInput` from R

```r
startApplication("appUpdate")
```

### Editable row and column names

- Edit row and column names by clicking on the cell
- The result will be shown on the right

```r
startApplication("appRownames")
```

### Uneditable cells

- Make table cells uneditable
- No clicking into cells, no changing values

```r
startApplication("appUneditableCells")
```

### Extend Matrix Automatically

- If matrix is full (last row and columns contain values) rows and columns are added automatically 


```r
startApplication("appExtend")
```

### Custom Column Header

- Replace default header with a multiheader
- Automatically add 2 columns if matrix is full

```r
startApplication("appDoubleHeader")
```

### Delete Rows and Columns

- add a button to delete rows and columns. This also works for multiheader.

```r
startApplication("appDelete")
```

### Lazy Update of server values

- Only update data on server when no input field is visible

```r
startApplication("appLazy")
```

