Skip to content

Commit 3446afd

Browse files
committed
Move input handlers to separate file
1 parent b12fef6 commit 3446afd

File tree

5 files changed

+106
-106
lines changed

5 files changed

+106
-106
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Collate:
120120
'reactives.R'
121121
'render-plot.R'
122122
'run-url.R'
123+
'server-input-handlers.R'
123124
'server.R'
124125
'shiny.R'
125126
'shinyui.R'

R/server-input-handlers.R

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

R/server.R

Lines changed: 1 addition & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,7 @@
1-
#' @include globals.R
1+
#' @include server-input-handlers.R
22

33
appsByToken <- Map$new()
44

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-
1085
# Provide a character representation of the WS that can be used
1096
# as a key in a Map.
1107
wsToKey <- function(WS) {

man/registerInputHandler.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
% Generated by roxygen2 (4.1.1): do not edit by hand
2-
% Please edit documentation in R/server.R
2+
% Please edit documentation in R/server-input-handlers.R
33
\name{registerInputHandler}
44
\alias{registerInputHandler}
55
\title{Register an Input Handler}

man/removeInputHandler.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
% Generated by roxygen2 (4.1.1): do not edit by hand
2-
% Please edit documentation in R/server.R
2+
% Please edit documentation in R/server-input-handlers.R
33
\name{removeInputHandler}
44
\alias{removeInputHandler}
55
\title{Deregister an Input Handler}

0 commit comments

Comments
 (0)