|
1 |
| -#' @include globals.R |
| 1 | +#' @include server-input-handlers.R |
2 | 2 |
|
3 | 3 | appsByToken <- Map$new()
|
4 | 4 |
|
5 |
| -# Create a map for input handlers and register the defaults. |
6 |
| -inputHandlers <- Map$new() |
7 |
| - |
8 |
| -#' Register an Input Handler |
9 |
| -#' |
10 |
| -#' Adds an input handler for data of this type. When called, Shiny will use the |
11 |
| -#' function provided to refine the data passed back from the client (after being |
12 |
| -#' deserialized by jsonlite) before making it available in the \code{input} |
13 |
| -#' variable of the \code{server.R} file. |
14 |
| -#' |
15 |
| -#' This function will register the handler for the duration of the R process |
16 |
| -#' (unless Shiny is explicitly reloaded). For that reason, the \code{type} used |
17 |
| -#' should be very specific to this package to minimize the risk of colliding |
18 |
| -#' with another Shiny package which might use this data type name. We recommend |
19 |
| -#' the format of "packageName.widgetName". |
20 |
| -#' |
21 |
| -#' Currently Shiny registers the following handlers: \code{shiny.matrix}, |
22 |
| -#' \code{shiny.number}, and \code{shiny.date}. |
23 |
| -#' |
24 |
| -#' The \code{type} of a custom Shiny Input widget will be deduced using the |
25 |
| -#' \code{getType()} JavaScript function on the registered Shiny inputBinding. |
26 |
| -#' @param type The type for which the handler should be added -- should be a |
27 |
| -#' single-element character vector. |
28 |
| -#' @param fun The handler function. This is the function that will be used to |
29 |
| -#' parse the data delivered from the client before it is available in the |
30 |
| -#' \code{input} variable. The function will be called with the following three |
31 |
| -#' parameters: |
32 |
| -#' \enumerate{ |
33 |
| -#' \item{The value of this input as provided by the client, deserialized |
34 |
| -#' using jsonlite.} |
35 |
| -#' \item{The \code{shinysession} in which the input exists.} |
36 |
| -#' \item{The name of the input.} |
37 |
| -#' } |
38 |
| -#' @param force If \code{TRUE}, will overwrite any existing handler without |
39 |
| -#' warning. If \code{FALSE}, will throw an error if this class already has |
40 |
| -#' a handler defined. |
41 |
| -#' @examples |
42 |
| -#' \dontrun{ |
43 |
| -#' # Register an input handler which rounds a input number to the nearest integer |
44 |
| -#' registerInputHandler("mypackage.validint", function(x, shinysession, name) { |
45 |
| -#' if (is.null(x)) return(NA) |
46 |
| -#' round(x) |
47 |
| -#' }) |
48 |
| -#' |
49 |
| -#' ## On the Javascript side, the associated input binding must have a corresponding getType method: |
50 |
| -#' getType: function(el) { |
51 |
| -#' return "mypackage.validint"; |
52 |
| -#' } |
53 |
| -#' |
54 |
| -#' } |
55 |
| -#' @seealso \code{\link{removeInputHandler}} |
56 |
| -#' @export |
57 |
| -registerInputHandler <- function(type, fun, force=FALSE){ |
58 |
| - if (inputHandlers$containsKey(type) && !force){ |
59 |
| - stop("There is already an input handler for type: ", type) |
60 |
| - } |
61 |
| - inputHandlers$set(type, fun) |
62 |
| -} |
63 |
| - |
64 |
| -#' Deregister an Input Handler |
65 |
| -#' |
66 |
| -#' Removes an Input Handler. Rather than using the previously specified handler |
67 |
| -#' for data of this type, the default jsonlite serialization will be used. |
68 |
| -#' |
69 |
| -#' @param type The type for which handlers should be removed. |
70 |
| -#' @return The handler previously associated with this \code{type}, if one |
71 |
| -#' existed. Otherwise, \code{NULL}. |
72 |
| -#' @seealso \code{\link{registerInputHandler}} |
73 |
| -#' @export |
74 |
| -removeInputHandler <- function(type){ |
75 |
| - inputHandlers$remove(type) |
76 |
| -} |
77 |
| - |
78 |
| -# Takes a list-of-lists and returns a matrix. The lists |
79 |
| -# must all be the same length. NULL is replaced by NA. |
80 |
| -registerInputHandler("shiny.matrix", function(data, ...) { |
81 |
| - if (length(data) == 0) |
82 |
| - return(matrix(nrow=0, ncol=0)) |
83 |
| - |
84 |
| - m <- matrix(unlist(lapply(data, function(x) { |
85 |
| - sapply(x, function(y) { |
86 |
| - ifelse(is.null(y), NA, y) |
87 |
| - }) |
88 |
| - })), nrow = length(data[[1]]), ncol = length(data)) |
89 |
| - return(m) |
90 |
| -}) |
91 |
| - |
92 |
| -registerInputHandler("shiny.number", function(val, ...){ |
93 |
| - ifelse(is.null(val), NA, val) |
94 |
| -}) |
95 |
| - |
96 |
| -registerInputHandler("shiny.date", function(val, ...){ |
97 |
| - # First replace NULLs with NA, then convert to Date vector |
98 |
| - datelist <- ifelse(lapply(val, is.null), NA, val) |
99 |
| - as.Date(unlist(datelist)) |
100 |
| -}) |
101 |
| - |
102 |
| -registerInputHandler("shiny.action", function(val, ...) { |
103 |
| - # mark up the action button value with a special class so we can recognize it later |
104 |
| - class(val) <- c(class(val), "shinyActionButtonValue") |
105 |
| - val |
106 |
| -}) |
107 |
| - |
108 | 5 | # Provide a character representation of the WS that can be used
|
109 | 6 | # as a key in a Map.
|
110 | 7 | wsToKey <- function(WS) {
|
|
0 commit comments