---
title: "The orderInput"
author: "Yang Tang"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{The orderInput}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r, include=FALSE}
library(shiny)
library(shinyjqui)
```

The `orderInput` display a list of strings and return their order as a vector in shiny input value. Users can drag and drop the strings to change their display order, and the binding shiny input value will update accordingly. Here is a simple example:

```{r, eval=FALSE}
server <- function(input, output) {
  output$order <- renderPrint({input$foo})
}

ui <- fluidPage(
  orderInput(inputId = 'foo', label = 'A simple example', items = c('A', 'B', 'C')),
  verbatimTextOutput('order')
)

shinyApp(ui, server)
```

![](fig/orderInput1.gif)

As showed in the above example, use `input$inputId` to get current order, where the "inputId" is the `inputId` parameter passed to the `orderInput` function.

The `items` parameter can either be a list, an atomic vector or a factor. Based on the type of data provided, the displayed strings and their corresponding order (returned in the shiny input value) are different. 

* For fully named list and vector (e.g. `c(A = "a", B = "b")`), orderInput display names (`A` and `B`) but return values (`a` and `b`) as order.
* For unnamed or partial named list and vector (e.g. `c("a", B = "b")`), values (`a` and `b`) are used both for display and order.
* For factor (e.g. `factor("a", "b")`), values (`a` and `b`) are displayed while it's levels (`1` and `2`) are used for order.

Multiple `orderInput`s can be connected to each other by passing their `inputId`s to the `connect` parameter. When connected, items from one `orderInput` can be dragged to another. See the following example:

```{r, eval=FALSE}
# items in A can be dragged to B
orderInput('A', 'A', items = 1:3, connect = 'B')
# items in B can be dragged to A
orderInput('B', 'B', items = 4:6, connect = 'A')
```

![](fig/orderInput2.gif)

A connected `orderInput` can run in source mode by setting `as_source = TRUE`. If an item is dragged from a source-mode-`orderInput` to other `orderInput`s, the item will not be removed from the original `orderInput`, that is, the operation become "copy" instead of "cut". See the following demonstration:

```{r, eval=FALSE}
# In source mode, items dragged to B are copied
orderInput('A', 'A', items = 1:3, connect = 'B', as_source = TRUE)
orderInput('B', 'B', items = 4:6)
```

![](fig/orderInput3.gif)

Items from non-source `orderInput` can be deleted by dragging them to a source `orderInput`:

```{r, eval=FALSE}
# Anything dropped into a "source" orderInput will be deleted
orderInput('A', 'A', items = 1:3, as_source = TRUE),
orderInput('B', 'B', items = 4:6)
```

![](fig/orderInput6.gif)

`orderInput` support `jqui_sortable`'s `save` and `load` operations and [shiny bookmarking](https://shiny.rstudio.com/articles/bookmarking-state.html). See Vignette `Save and restore` for more information. Here is an example:

```{r, eval=FALSE}
ui <- fluidPage(
  orderInput('A', 'A', items = 1:3, as_source = TRUE, connect = c("B", "C")),
  orderInput('B', 'B', items = 4:6, connect = "C"),
  orderInput('C', 'C', items = 7:9, connect = "B"),
  hr(),
  actionButton("save", "Save"),
  actionButton("load", "Load")
)
server <- function(input, output, session) {
  observeEvent(input$save, jqui_sortable("#B,#C", "save"))
  observeEvent(input$load, jqui_sortable("#B,#C", "load"))
}
```

![](fig/orderInput7.gif)

`placeholder` shows when there is no item in `orderInput`:

```{r, eval=FALSE}
orderInput('A', 'A', items = 1:3, connect = 'B')
orderInput('B', 'B', items = NULL, placeholder = 'Drag item here...')
```

![](fig/orderInput4.gif)

`orderInput` uses the six predefined Bootstrap button classes to style the displayed items. Choose one of them and set in the `item_class` parameter:

```{r, eval=FALSE}
orderInput('default', 'default', items = 1:3, item_class = 'default')
orderInput('primary', 'primary', items = 1:3, item_class = 'primary')
orderInput('success', 'success', items = 1:3, item_class = 'success')
orderInput('info', 'info', items = 1:3, item_class = 'info')
orderInput('warning', 'warning', items = 1:3, item_class = 'warning')
orderInput('danger', 'danger', items = 1:3, item_class = 'danger')
```

![](fig/orderInput5.png)
