Compare commits

..

10 Commits

Author SHA1 Message Date
Joe Cheng
e9fc873c8d Restore HTML generating functions
These functions were temporarily ripped out of Shiny and moved
to the htmltools package. We've discovered that it's safe to
keep including them in shiny; as long as the functions in shiny
and the functions in htmltools are identical, the user won't
receive a conflict warning.
2014-05-29 14:00:48 -07:00
Joe Cheng
0153349979 Make S3 method consistent with base 2014-05-28 13:28:02 -07:00
Joe Cheng
d227842414 Update htmltools version 2014-05-28 13:20:54 -07:00
Joe Cheng
b6a2122a41 Merge remote-tracking branch 'origin/master' into htmltools-refactor
Conflicts:
	R/shiny.R
	man/session.Rd
2014-05-28 13:18:49 -07:00
Joe Cheng
78f87d9003 Dependency fixes
1) Give bootstrap deps a path so they can be used in static docs
2) Resolve dependencies before rendering page (whoops)
2014-05-16 15:39:08 -07:00
Joe Cheng
0824726dbb Adapt to htmltools 0.2.1 API 2014-05-15 15:17:42 -07:00
Joe Cheng
f55155404a Remove obsolete entry from staticdocs index 2014-05-14 17:13:38 -07:00
Joe Cheng
b711bb553f Add S3 method for turning render function into tags 2014-05-14 17:12:15 -07:00
Joe Cheng
2a36179bdc Fix broken client-side HTML dependency rendering 2014-05-14 17:12:15 -07:00
Joe Cheng
e57221861f Extract HTML functionality to htmltools library 2014-05-14 17:12:15 -07:00
57 changed files with 656 additions and 928 deletions

1
.gitattributes vendored
View File

@@ -1 +0,0 @@
/NEWS merge=union

View File

@@ -10,13 +10,12 @@ install:
- sudo apt-add-repository -y "deb http://cran.rstudio.com/bin/linux/ubuntu `lsb_release -cs`/"
- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
- sudo apt-add-repository -y ppa:marutter/c2d4u
- sudo apt-get -qq update
- sudo apt-get -qq install r-base r-cran-shiny r-cran-cairo r-cran-markdown r-cran-knitr
- sudo apt-get update
- sudo apt-get install r-base-dev r-cran-shiny r-cran-cairo r-cran-markdown
- "[ ! -d ~/R ] && mkdir ~/R"
- echo "options(repos = c(CRAN = 'http://cran.rstudio.com'))" > ~/.Rprofile
- Rscript -e "install.packages(c('xtable'), quiet = TRUE)"
- Rscript -e "update.packages(instlib = '~/R', ask = FALSE, quiet = TRUE)"
- Rscript -e "install.packages('$R_MY_PKG', dep = TRUE, quiet = TRUE)"
- Rscript -e "install.packages(c('xtable'), repos = 'http://cran.rstudio.org')"
- Rscript -e "install.packages('knitr', repos = c('http://rforge.net', 'http://cran.rstudio.org'))"
- Rscript -e "install.packages('$R_MY_PKG', dep = TRUE, repos = 'http://cran.rstudio.org')"
# run tests
script:

View File

@@ -1,8 +1,8 @@
Package: shiny
Type: Package
Title: Web Application Framework for R
Version: 0.10.1.9001
Date: 2014-06-13
Version: 0.9.1.9008
Date: 2014-03-19
Author: RStudio, Inc.
Maintainer: Winston Chang <winston@rstudio.com>
Description: Shiny makes it incredibly easy to build interactive web
@@ -11,12 +11,13 @@ Description: Shiny makes it incredibly easy to build interactive web
beautiful, responsive, and powerful applications with minimal effort.
License: GPL-3
Depends:
R (>= 3.0.0),
R (>= 2.14.1),
methods
Imports:
tools,
utils,
httpuv (>= 1.2.2),
httpuv (>= 1.2.0),
caTools,
RJSONIO,
xtable,
digest,
@@ -29,6 +30,7 @@ Suggests:
markdown
URL: http://www.rstudio.com/shiny/
BugReports: https://github.com/rstudio/shiny/issues
Roxygen: list(wrap = FALSE)
Collate:
'app.R'
'bootstrap-layout.R'

View File

@@ -17,7 +17,6 @@ S3method(as.list,reactivevalues)
S3method(as.shiny.appobj,character)
S3method(as.shiny.appobj,list)
S3method(as.shiny.appobj,shiny.appobj)
S3method(as.tags,shiny.appobj)
S3method(as.tags,shiny.render.function)
S3method(names,reactivevalues)
S3method(print,reactive)
@@ -81,11 +80,8 @@ export(is.reactive)
export(is.reactivevalues)
export(is.singleton)
export(isolate)
export(knit_print.html)
export(knit_print.shiny.appobj)
export(knit_print.shiny.render.function)
export(knit_print.shiny.tag)
export(knit_print.shiny.tag.list)
export(mainPanel)
export(makeReactiveBinding)
export(markRenderFunction)
@@ -133,7 +129,6 @@ export(runGitHub)
export(runUrl)
export(selectInput)
export(selectizeInput)
export(serverInfo)
export(shinyApp)
export(shinyAppDir)
export(shinyServer)
@@ -181,9 +176,10 @@ export(wellPanel)
export(withMathJax)
export(withReactiveDomain)
export(withTags)
import(RJSONIO)
import(caTools)
import(digest)
import(htmltools)
import(httpuv)
import(methods)
import(xtable)
importFrom(RJSONIO,fromJSON)

71
NEWS
View File

@@ -1,51 +1,9 @@
shiny 0.10.1.9xxx
--------------------------------------------------------------------------------
* Fixed #557: updateSelectizeInput(choices, server = TRUE) did not work when
`chocies` is a character vector.
shiny 0.10.1
--------------------------------------------------------------------------------
* Added Unicode support for Windows. Shiny apps running on Windows must use the
UTF-8 encoding for ui.R and server.R (also the optional global.R) if they
contain non-ASCII characters. See this article for details and examples:
http://shiny.rstudio.com/gallery/unicode-characters.html (#516)
* `runGitHub()` also allows the 'username/repo' syntax now, which is equivalent
to `runGitHub('repo', 'username')`. (#427)
* `navbarPage()` now accepts a `windowTitle` parameter to set the web browser
page title to something other than the title displayed in the navbar.
* Added an `inline` argument to `textOutput()`, `imageOutput()`, `plotOutput()`,
and `htmlOutput()`. When `inline = TRUE`, these outputs will be put in
`span()` instead of the default `div()`. This occurs automatically when these
outputs are created via the inline expressions (e.g. `r renderText(expr)`) in
R Markdown documents. See an R Markdown example at
http://shiny.rstudio.com/gallery/inline-output.html (#512)
* Added support for option groups in the select/selectize inputs. When the
`choices` argument for `selectInput()`/`selectizeInput()` is a list of
sub-lists and any sub-list is of length greater than 1, the HTML tag
`<optgroup>` will be used. See an example at
http://shiny.rstudio.com/gallery/option-groups-for-selectize-input.html (#542)
shiny 0.10.0
shiny 0.9.1.9XXX
--------------------------------------------------------------------------------
* BREAKING CHANGE: By default, observers now terminate themselves if they were
created during a session and that session ends. See ?domains for more details.
* Shiny can now be used in R Markdown v2 documents, to create "Shiny Docs":
reports and presentations that combine narrative, statically computed output,
and fully dynamic inputs and outputs. For more info, including examples, see
http://rmarkdown.rstudio.com/authoring_shiny.html.
* The `session` object that can be passed into a server function (e.g.
shinyServer(function(input, output, session) {...})) is now documented: see
`?session`.
* Most inputs can now accept `NULL` label values to omit the label altogether.
* New `actionLink` input control; like `actionButton`, but with the appearance
@@ -54,39 +12,20 @@ shiny 0.10.0
* `renderPlot` now calls `print` on its result if it's visible (i.e. no more
explicit `print()` required for ggplot2).
* Introduced Shiny app objects (see `?shinyApp`). These essentially replace the
little-advertised ability for `runApp` to take a `list(ui=..., server=...)`
as the first argument instead of a directory (though that ability remains for
backward compatibility). Unlike those lists, Shiny app objects are tagged with
class `shiny.appobj` so they can be run simply by printing them.
* Added `maskReactiveContext` function. It blocks the current reactive context,
to evaluate expressions that shouldn't use reactive sources directly. (This
should not be commonly needed.)
* Added `flowLayout`, `splitLayout`, and `inputPanel` functions for putting UI
elements side by side. `flowLayout` lays out its children in a left-to-right,
elements side by side. `flowPanel` lays out its children in a left-to-right,
top-to-bottom arrangement. `splitLayout` evenly divides its horizontal space
among its children (or unevenly divides if `cellWidths` argument is provided).
`inputPanel` is like `flowPanel`, but with a light grey background, and is
intended to be used to encapsulate small input controls wherever vertical
space is at a premium.
* Added `serverInfo` to obtain info about the Shiny Server if the app is served
through it.
* Added an `inline` argument (TRUE/FALSE) in `checkboxGroupInput()` and
`radioButtons()` to allow the horizontal layout (inline = TRUE) of checkboxes
or radio buttons. (Thanks, @saurfang, #481)
* `sliderInput` and `selectizeInput`/`selectInput` now use a standard horizontal
size instead of filling up all available horizontal space. Pass `width="100%"`
explicitly for the old behavior.
* Added the `updateSelectizeInput()` function to make it possible to process
searching on the server side (i.e. using R), which can be much faster than the
client side processing (i.e. using HTML and JavaScript). See the article at
http://shiny.rstudio.com/articles/selectize.html for a detailed introduction.
size instead of filling up all available horizontal space.
* Fixed a bug of renderDataTable() when the data object only has 1 row and 1
column. (Thanks, ZJ Dai, #429)
@@ -97,10 +36,6 @@ shiny 0.10.0
* Fixed #220: the zip file for a directory created by some programs may not have
the directory name as its first entry, in which case runUrl() can fail. (#220)
* `runGitHub()` can also take a value of the form "username/repo" in its first
argument, e.g. both runGitHub("shiny_example", "rstudio") and
runGitHub("rstudio/shiny_example") are valid ways to run the GitHub repo.
shiny 0.9.1
--------------------------------------------------------------------------------

70
R/app.R
View File

@@ -69,7 +69,7 @@ shinyApp <- function(ui, server, onStart=NULL, options=list(), uiPattern="/") {
renderPage(uiValue, textConn)
html <- paste(textConnectionValue(textConn), collapse='\n')
return(httpResponse(200, content=enc2utf8(html)))
return(httpResponse(200, content=html))
}
serverFuncSource <- function() {
@@ -112,7 +112,9 @@ shinyAppDir <- function(appDir, options=list()) {
# If not, then take the last expression that's returned from ui.R.
.globals$ui <- NULL
on.exit(.globals$ui <- NULL, add = FALSE)
ui <- sourceUTF8(uiR, local = new.env(parent = globalenv()))$value
ui <- source(uiR,
local = new.env(parent = globalenv()),
keep.source = TRUE)$value
if (!is.null(.globals$ui)) {
ui <- .globals$ui[[1]]
}
@@ -135,7 +137,11 @@ shinyAppDir <- function(appDir, options=list()) {
# server.R.
.globals$server <- NULL
on.exit(.globals$server <- NULL, add = TRUE)
result <- sourceUTF8(serverR, local = new.env(parent = globalenv()))$value
result <- source(
serverR,
local = new.env(parent = globalenv()),
keep.source = TRUE
)$value
if (!is.null(.globals$server)) {
result <- .globals$server[[1]]
}
@@ -163,7 +169,7 @@ shinyAppDir <- function(appDir, options=list()) {
oldwd <<- getwd()
setwd(appDir)
if (file.exists(file.path.ci(appDir, "global.R")))
sourceUTF8(file.path.ci(appDir, "global.R"))
source(file.path.ci(appDir, "global.R"), keep.source = TRUE)
}
onEnd <- function() {
setwd(oldwd)
@@ -218,21 +224,6 @@ print.shiny.appobj <- function(x, ...) {
do.call(runApp, args)
}
#' @rdname shinyApp
#' @method as.tags shiny.appobj
#' @export
as.tags.shiny.appobj <- function(x, ...) {
# jcheng 06/06/2014: Unfortunate copy/paste between this function and
# knit_print.shiny.appobj, but I am trying to make the most conservative
# change possible due to upcoming release.
opts <- x$options %OR% list()
width <- if (is.null(opts$width)) "100%" else opts$width
height <- if (is.null(opts$height)) "400" else opts$height
path <- addSubApp(x)
tags$iframe(src=path, width=width, height=height, class="shiny-frame")
}
#' Knitr S3 methods
#'
#' These S3 methods are necessary to help Shiny applications and UI chunks embed
@@ -243,33 +234,26 @@ as.tags.shiny.appobj <- function(x, ...) {
#' @param ... Additional knit_print arguments
NULL
# If there's an R Markdown runtime option set but it isn't set to Shiny, then
# return a warning indicating the runtime is inappropriate for this object.
# Returns NULL in all other cases.
shiny_rmd_warning <- function() {
runtime <- knitr::opts_knit$get("rmarkdown.runtime")
if (!is.null(runtime) && runtime != "shiny")
# note that the RStudio IDE checks for this specific string to detect Shiny
# applications in static document
list(structure(
"Shiny application in a static R Markdown document",
class = "rmd_warning"))
else
NULL
}
#' @rdname knitr_methods
#' @export
knit_print.shiny.appobj <- function(x, ...) {
opts <- x$options %OR% list()
width <- if (is.null(opts$width)) "100%" else opts$width
height <- if (is.null(opts$height)) "400" else opts$height
shiny_warning <- NULL
# if there's an R Markdown runtime option set but it isn't set to Shiny, then
# emit a warning indicating the runtime is inappropriate for this object
runtime <- knitr::opts_knit$get("rmarkdown.runtime")
if (!is.null(runtime) && runtime != "shiny") {
# If not rendering to a Shiny document, create a box exactly the same
# dimensions as the Shiny app would have had (so the document continues to
# flow as it would have with the app), and display a diagnostic message
# note that the RStudio IDE checks for this specific string to detect Shiny
# applications in static document
shiny_warning <- list(structure(
"Shiny application in a static R Markdown document",
class = "rmd_warning"))
# create a box exactly the same dimensions as the Shiny app would have had
# (so the document continues to flow as it would have with the app), and
# display a diagnostic message
width <- validateCssUnit(width)
height <- validateCssUnit(height)
output <- tags$div(
@@ -290,19 +274,15 @@ knit_print.shiny.appobj <- function(x, ...) {
# for now it's not an issue, so just return the HTML and warning.
knitr::asis_output(htmlPreserve(format(output, indent=FALSE)),
meta = shiny_rmd_warning(), cacheable = FALSE)
meta = shiny_warning, cacheable = FALSE)
}
# Let us use a nicer syntax in knitr chunks than literally
# Lets us use a nicer syntax in knitr chunks than literally
# calling output$value <- renderFoo(...) and fooOutput().
#' @rdname knitr_methods
#' @param inline Whether the object is printed inline.
#' @export
knit_print.shiny.render.function <- function(x, ..., inline = FALSE) {
x <- htmltools::as.tags(x, inline = inline)
knit_print.shiny.render.function <- function(x, ...) {
output <- knitr::knit_print(tagList(x))
attr(output, "knit_cacheable") <- FALSE
attr(output, "knit_meta") <- append(attr(output, "knit_meta"),
shiny_rmd_warning())
output
}

View File

@@ -320,7 +320,7 @@ verticalLayout <- function(..., fluid = TRUE) {
#'
#' @seealso \code{\link{verticalLayout}}
#'
#' @examples
#' #' @examples
#' flowLayout(
#' numericInput("rows", "How many rows?", 5),
#' selectInput("letter", "Which letter?", LETTERS),
@@ -370,7 +370,7 @@ inputPanel <- function(...) {
#' @param cellArgs Any additional attributes that should be used for each cell
#' of the layout.
#'
#' @examples
#' #' @examples
#' # Equal sizing
#' splitLayout(
#' plotOutput("plot1"),

View File

@@ -160,8 +160,6 @@ pageWithSidebar <- function(headerPanel,
#' @param theme Alternative Bootstrap stylesheet (normally a css file within the
#' www directory). For example, to use the theme located at
#' \code{www/bootstrap.css} you would use \code{theme = "bootstrap.css"}.
#' @param windowTitle The title that should be displayed by the browser window.
#' Useful if \code{title} is not a string.
#' @param icon Optional icon to appear on a \code{navbarMenu} tab.
#'
#' @return A UI defintion that can be passed to the \link{shinyUI} function.
@@ -196,8 +194,7 @@ navbarPage <- function(title,
collapsable = FALSE,
fluid = TRUE,
responsive = TRUE,
theme = NULL,
windowTitle = title) {
theme = NULL) {
# alias title so we can avoid conflicts w/ title in withTags
pageTitle <- title
@@ -262,7 +259,7 @@ navbarPage <- function(title,
# build the page
bootstrapPage(
title = windowTitle,
title = title,
responsive = responsive,
theme = theme,
div(class=navbarClass,
@@ -384,11 +381,6 @@ mainPanel <- function(..., width = 8) {
#' determine whether the panel should be displayed.
#' @param ... Elements to include in the panel.
#'
#' @note You are not recommended to use special JavaScript characters such as a
#' period \code{.} in the input id's, but if you do use them anyway, for
#' example, \code{inputId = "foo.bar"}, you will have to use
#' \code{input["foo.bar"]} instead of \code{input.foo.bar} to read the input
#' value.
#' @examples
#' sidebarPanel(
#' selectInput(
@@ -565,7 +557,6 @@ checkboxInput <- function(inputId, label, value = FALSE) {
#' @param choices List of values to show checkboxes for. If elements of the list
#' are named then that name rather than the value is displayed to the user.
#' @param selected The values that should be initially selected, if any.
#' @param inline If \code{TRUE}, render the choices inline (i.e. horizontally)
#' @return A list of HTML elements that can be added to a UI definition.
#'
#' @family input elements
@@ -578,19 +569,37 @@ checkboxInput <- function(inputId, label, value = FALSE) {
#' "Gears" = "gear"))
#'
#' @export
checkboxGroupInput <- function(inputId, label, choices, selected = NULL, inline = FALSE) {
checkboxGroupInput <- function(inputId, label, choices, selected = NULL) {
# resolve names
choices <- choicesWithNames(choices)
if (!is.null(selected))
selected <- validateSelected(selected, choices, inputId)
options <- generateOptions(inputId, choices, selected, inline)
# Create tags for each of the options
ids <- paste0(inputId, seq_along(choices))
checkboxes <- mapply(ids, choices, names(choices),
SIMPLIFY = FALSE, USE.NAMES = FALSE,
FUN = function(id, value, name) {
inputTag <- tags$input(type = "checkbox",
name = inputId,
id = id,
value = value)
if (value %in% selected)
inputTag$attribs$checked <- "checked"
tags$label(class = "checkbox",
inputTag,
tags$span(name))
}
)
# return label and select tag
tags$div(id = inputId,
class = "control-group shiny-input-checkboxgroup",
controlLabel(inputId, label),
options)
checkboxes)
}
# Before shiny 0.9, `selected` refers to names/labels of `choices`; now it
@@ -598,12 +607,11 @@ checkboxGroupInput <- function(inputId, label, choices, selected = NULL, inline
validateSelected <- function(selected, choices, inputId) {
# drop names, otherwise toJSON() keeps them too
selected <- unname(selected)
# if you are using optgroups, you're using shiny > 0.10.0, and you should
# already know that `selected` must be a value instead of a label
if (needOptgroup(choices)) return(selected)
if (is.list(choices)) choices <- unlist(choices)
if (is.list(choices)) {
# <optgroup> is not there yet
if (any(sapply(choices, length) > 1)) return(selected)
choices <- unlist(choices)
}
nms <- names(choices)
# labels and values are identical, no need to validate
if (identical(nms, unname(choices))) return(selected)
@@ -621,29 +629,6 @@ validateSelected <- function(selected, choices, inputId) {
selected
}
# generate options for radio buttons and checkbox groups (type = 'checkbox' or
# 'radio')
generateOptions <- function(inputId, choices, selected, inline, type = 'checkbox') {
# create tags for each of the options
ids <- paste0(inputId, seq_along(choices))
# generate a list of <input type=? [checked] />
mapply(
ids, choices, names(choices),
FUN = function(id, value, name) {
inputTag <- tags$input(
type = type, name = inputId, id = id, value = value
)
if (value %in% selected)
inputTag$attribs$checked <- "checked"
tags$label(
class = paste(type, if (inline) "inline"),
inputTag, tags$span(name)
)
},
SIMPLIFY = FALSE, USE.NAMES = FALSE
)
}
#' Create a help text element
#'
#' Create help text which can be added to an input form to provide additional
@@ -668,43 +653,20 @@ controlLabel <- function(controlName, label) {
# Takes a vector or list, and adds names (same as the value) to any entries
# without names.
choicesWithNames <- function(choices) {
# Take a vector or list, and convert to list. Also, if any children are
# vectors with length > 1, convert those to list. If the list is unnamed,
# convert it to a named list with blank names.
listify <- function(obj) {
# If a list/vector is unnamed, give it blank names
makeNamed <- function(x) {
if (is.null(names(x))) names(x) <- character(length(x))
x
}
if (is.null(choices)) return(choices) # ignore NULL
res <- lapply(obj, function(val) {
if (is.list(val))
listify(val)
else if (length(val) == 1 && is.null(names(val)))
val
else
makeNamed(as.list(val))
})
makeNamed(res)
}
choices <- listify(choices)
if (length(choices) == 0) return(choices)
# Recurse into any subgroups
choices <- mapply(choices, names(choices), FUN = function(choice, name) {
if (!is.list(choice)) return(choice)
if (name == "") stop('All sub-lists in "choices" must be named.')
choicesWithNames(choice)
}, SIMPLIFY = FALSE)
# get choice names
choiceNames <- names(choices)
if (is.null(choiceNames))
choiceNames <- character(length(choices))
# default missing names to choice values
missing <- names(choices) == ""
names(choices)[missing] <- as.character(choices)[missing]
missingNames <- choiceNames == ""
choiceNames[missingNames] <- paste(choices)[missingNames]
names(choices) <- choiceNames
choices
# return choices
return (choices)
}
#' Create a select list input control
@@ -744,11 +706,21 @@ selectInput <- function(inputId, label, choices, selected = NULL,
# default value if it's not specified
if (is.null(selected)) {
if (!multiple) selected <- firstChoice(choices)
if (!multiple) selected <- choices[[1]]
} else selected <- validateSelected(selected, choices, inputId)
# Create tags for each of the options
options <- HTML(paste("<option value=\"",
htmlEscape(choices),
"\"",
ifelse(choices %in% selected, " selected", ""),
">",
htmlEscape(names(choices)),
"</option>",
sep = "", collapse = "\n"));
# create select tag and add options
selectTag <- tags$select(id = inputId, selectOptions(choices, selected))
selectTag <- tags$select(id = inputId, options)
if (multiple)
selectTag$attribs$multiple <- "multiple"
@@ -758,44 +730,6 @@ selectInput <- function(inputId, label, choices, selected = NULL,
selectizeIt(inputId, res, NULL, width, nonempty = !multiple && !("" %in% choices))
}
firstChoice <- function(choices) {
if (length(choices) == 0L) return()
choice <- choices[[1]]
if (is.list(choice)) firstChoice(choice) else choice
}
# Create tags for each of the options; use <optgroup> if necessary.
# This returns a HTML string instead of tags, because of the 'selected'
# attribute.
selectOptions <- function(choices, selected = NULL) {
html <- mapply(choices, names(choices), FUN = function(choice, label) {
if (is.list(choice)) {
# If sub-list, create an optgroup and recurse into the sublist
sprintf(
'<optgroup label="%s">\n%s\n</optgroup>',
htmlEscape(label),
selectOptions(choice, selected)
)
} else {
# If single item, just return option string
sprintf(
'<option value="%s"%s>%s</option>',
htmlEscape(choice),
if (choice %in% selected) ' selected' else '',
htmlEscape(label)
)
}
})
HTML(paste(html, collapse = '\n'))
}
# need <optgroup> when choices contains sub-lists
needOptgroup <- function(choices) {
any(vapply(choices, is.list, logical(1)))
}
#' @rdname selectInput
#' @param ... Arguments passed to \code{selectInput()}.
#' @param options A list of options. See the documentation of \pkg{selectize.js}
@@ -856,7 +790,6 @@ selectizeIt <- function(inputId, select, options, width = NULL, nonempty = FALSE
#' named then that name rather than the value is displayed to the user)
#' @param selected The initially selected value (if not specified then
#' defaults to the first value)
#' @param inline If \code{TRUE}, render the choices inline (i.e. horizontally)
#' @return A set of radio buttons that can be added to a UI definition.
#'
#' @family input elements
@@ -869,7 +802,7 @@ selectizeIt <- function(inputId, select, options, width = NULL, nonempty = FALSE
#' "Log-normal" = "lnorm",
#' "Exponential" = "exp"))
#' @export
radioButtons <- function(inputId, label, choices, selected = NULL, inline = FALSE) {
radioButtons <- function(inputId, label, choices, selected = NULL) {
# resolve names
choices <- choicesWithNames(choices)
@@ -877,14 +810,33 @@ radioButtons <- function(inputId, label, choices, selected = NULL, inline = FALS
selected <- if (is.null(selected)) choices[[1]] else {
validateSelected(selected, choices, inputId)
}
if (length(selected) > 1) stop("The 'selected' argument must be of length 1")
options <- generateOptions(inputId, choices, selected, inline, type = 'radio')
# Create tags for each of the options
ids <- paste0(inputId, seq_along(choices))
inputTags <- mapply(ids, choices, names(choices),
SIMPLIFY = FALSE, USE.NAMES = FALSE,
FUN = function(id, value, name) {
inputTag <- tags$input(type = "radio",
name = inputId,
id = id,
value = value)
if (identical(value, selected))
inputTag$attribs$checked = "checked"
# Put the label text in a span
tags$label(class = "radio",
inputTag,
tags$span(name)
)
}
)
tags$div(id = inputId,
class = 'control-group shiny-input-radiogroup',
label %AND% tags$label(class = "control-label", `for` = inputId, label),
options)
inputTags)
}
#' Create a submit button
@@ -1536,15 +1488,13 @@ buildTabset <- function(tabs,
#' text will be included within an HTML \code{div} tag by default.
#' @param outputId output variable to read the value from
#' @param container a function to generate an HTML element to contain the text
#' @param inline use an inline (\code{span()}) or block container (\code{div()})
#' for the output
#' @return A text output element that can be included in a panel
#' @details Text is HTML-escaped prior to rendering. This element is often used
#' to display \link{renderText} output variables.
#' to display \link{renderText} output variables.
#' @examples
#' h3(textOutput("caption"))
#' @export
textOutput <- function(outputId, container = if (inline) span else div, inline = FALSE) {
textOutput <- function(outputId, container = div) {
container(id = outputId, class = "shiny-text-output")
}
@@ -1578,7 +1528,6 @@ verbatimTextOutput <- function(outputId) {
#' \code{"400px"}, \code{"auto"}) or a number, which will be coerced to a
#' string and have \code{"px"} appended.
#' @param height Image height
#' @inheritParams textOutput
#' @return An image output element that can be included in a panel
#' @examples
#' # Show an image
@@ -1586,45 +1535,38 @@ verbatimTextOutput <- function(outputId) {
#' imageOutput("dataImage")
#' )
#' @export
imageOutput <- function(outputId, width = "100%", height="400px", inline=FALSE) {
imageOutput <- function(outputId, width = "100%", height="400px") {
style <- paste("width:", validateCssUnit(width), ";",
"height:", validateCssUnit(height))
container <- if (inline) span else div
container(id = outputId, class = "shiny-image-output", style = style)
div(id = outputId, class = "shiny-image-output", style = style)
}
#' Create an plot output element
#'
#' Render a \link{renderPlot} within an application page.
#' @param outputId output variable to read the plot from
#' @param width,height Plot width/height. Must be a valid CSS unit (like
#' \code{"100\%"}, \code{"400px"}, \code{"auto"}) or a number, which will be
#' coerced to a string and have \code{"px"} appended. These two arguments are
#' ignored when \code{inline = TRUE}, in which case the width/height of a plot
#' must be specified in \code{renderPlot()}.
#' @param width Plot width. Must be a valid CSS unit (like \code{"100\%"},
#' \code{"400px"}, \code{"auto"}) or a number, which will be coerced to a
#' string and have \code{"px"} appended.
#' @param height Plot height
#' @param clickId If not \code{NULL}, the plot will send coordinates to the
#' server whenever it is clicked. This information will be accessible on the
#' \code{input} object using \code{input$}\emph{\code{clickId}}. The value
#' will be a named list or vector with \code{x} and \code{y} elements
#' indicating the mouse position in user units.
#' \code{input} object using \code{input$}\emph{\code{clickId}}. The value will be a
#' named list or vector with \code{x} and \code{y} elements indicating the
#' mouse position in user units.
#' @param hoverId If not \code{NULL}, the plot will send coordinates to the
#' server whenever the mouse pauses on the plot for more than the number of
#' milliseconds determined by \code{hoverTimeout}. This information will be
#' accessible on the \code{input} object using
#' \code{input$}\emph{\code{clickId}}. The value will be \code{NULL} if the
#' user is not hovering, and a named list or vector with \code{x} and \code{y}
#' elements indicating the mouse position in user units.
# accessible on the \code{input} object using \code{input$}\emph{\code{clickId}}.
#' The value will be \code{NULL} if the user is not hovering, and a named
#' list or vector with \code{x} and \code{y} elements indicating the mouse
#' position in user units.
#' @param hoverDelay The delay for hovering, in milliseconds.
#' @param hoverDelayType The type of algorithm for limiting the number of hover
#' events. Use \code{"throttle"} to limit the number of hover events to one
#' every \code{hoverDelay} milliseconds. Use \code{"debounce"} to suspend
#' events while the cursor is moving, and wait until the cursor has been at
#' rest for \code{hoverDelay} milliseconds before sending an event.
#' @inheritParams textOutput
#' @note The arguments \code{clickId} and \code{hoverId} only work for R base
#' graphics (see the \pkg{\link{graphics}} package). They do not work for
#' \pkg{\link[grid:grid-package]{grid}}-based graphics, such as \pkg{ggplot2},
#' \pkg{lattice}, and so on.
#' @return A plot output element that can be included in a panel
#' @examples
#' # Show a plot of the generated distribution
@@ -1634,7 +1576,7 @@ imageOutput <- function(outputId, width = "100%", height="400px", inline=FALSE)
#' @export
plotOutput <- function(outputId, width = "100%", height="400px",
clickId = NULL, hoverId = NULL, hoverDelay = 300,
hoverDelayType = c("debounce", "throttle"), inline = FALSE) {
hoverDelayType = c("debounce", "throttle")) {
if (is.null(clickId) && is.null(hoverId)) {
hoverDelay <- NULL
hoverDelayType <- NULL
@@ -1642,12 +1584,9 @@ plotOutput <- function(outputId, width = "100%", height="400px",
hoverDelayType <- match.arg(hoverDelayType)[[1]]
}
style <- if (!inline) {
paste("width:", validateCssUnit(width), ";", "height:", validateCssUnit(height))
}
container <- if (inline) span else div
container(id = outputId, class = "shiny-plot-output", style = style,
style <- paste("width:", validateCssUnit(width), ";",
"height:", validateCssUnit(height))
div(id = outputId, class = "shiny-plot-output", style = style,
`data-click-id` = clickId,
`data-hover-id` = hoverId,
`data-hover-delay` = hoverDelay,
@@ -1699,19 +1638,19 @@ dataTableOutput <- function(outputId) {
#' server side. It is currently just an alias for \code{htmlOutput}.
#'
#' @param outputId output variable to read the value from
#' @inheritParams textOutput
#' @return An HTML output element that can be included in a panel
#' @examples
#' htmlOutput("summary")
#' @export
htmlOutput <- function(outputId, inline = FALSE) {
container <- if (inline) span else div
container(id = outputId, class="shiny-html-output")
htmlOutput <- function(outputId) {
div(id = outputId, class="shiny-html-output")
}
#' @rdname htmlOutput
#' @export
uiOutput <- htmlOutput
uiOutput <- function(outputId) {
htmlOutput(outputId)
}
#' Create a download button or link
#'

View File

@@ -5,5 +5,5 @@
# R's lazy-loading package scheme causes the private seed to be cached in the
# package itself, making our PRNG completely deterministic. This line resets
# the private seed during load.
withPrivateSeed(reinitializeSeed())
withPrivateSeed(set.seed(NULL))
}

View File

@@ -55,10 +55,8 @@ renderReactLog <- function() {
}
.graphAppend <- function(logEntry, domain = getDefaultReactiveDomain()) {
if (isTRUE(getOption('shiny.reactlog'))) {
logEntry$session <- if (is.null(domain)) NULL else domain$token
if (isTRUE(getOption('shiny.reactlog', FALSE)))
.graphEnv$log <- c(.graphEnv$log, list(logEntry))
}
if (!is.null(domain)) {
domain$reactlog(logEntry)

View File

@@ -1,7 +1,101 @@
#' @export a br code div em h1 h2 h3 h4 h5 h6 hr HTML img p pre span strong
#' @export includeCSS includeHTML includeMarkdown includeScript includeText
#' @export is.singleton singleton
#' @export tag tagAppendAttributes tagAppendChild tagAppendChildren tagList tags tagSetChildren withTags
#' @export validateCssUnit
#' @export knit_print.html knit_print.shiny.tag knit_print.shiny.tag.list
NULL
#' @export
a <- htmltools::a
#' @export
br <- htmltools::br
#' @export
code <- htmltools::code
#' @export
div <- htmltools::div
#' @export
em <- htmltools::em
#' @export
h1 <- htmltools::h1
#' @export
h2 <- htmltools::h2
#' @export
h3 <- htmltools::h3
#' @export
h4 <- htmltools::h4
#' @export
h5 <- htmltools::h5
#' @export
h6 <- htmltools::h6
#' @export
hr <- htmltools::hr
#' @export
HTML <- htmltools::HTML
#' @export
img <- htmltools::img
#' @export
includeCSS <- htmltools::includeCSS
#' @export
includeHTML <- htmltools::includeHTML
#' @export
includeMarkdown <- htmltools::includeMarkdown
#' @export
includeScript <- htmltools::includeScript
#' @export
includeText <- htmltools::includeText
#' @export
is.singleton <- htmltools::is.singleton
#' @export
p <- htmltools::p
#' @export
pre <- htmltools::pre
#' @export
singleton <- htmltools::singleton
#' @export
span <- htmltools::span
#' @export
strong <- htmltools::strong
#' @export
tag <- htmltools::tag
#' @export
tagAppendAttributes <- htmltools::tagAppendAttributes
#' @export
tagAppendChild <- htmltools::tagAppendChild
#' @export
tagAppendChildren <- htmltools::tagAppendChildren
#' @export
tagList <- htmltools::tagList
#' @export
tags <- htmltools::tags
#' @export
tagSetChildren <- htmltools::tagSetChildren
#' @export
validateCssUnit <- htmltools::validateCssUnit
#' @export
withTags <- htmltools::withTags

View File

@@ -34,7 +34,7 @@ plotPNG <- function(func, filename=tempfile(fileext='.png'),
# Finally, if neither quartz nor Cairo, use png().
if (capabilities("aqua")) {
pngfun <- png
} else if ((getOption('shiny.usecairo') %OR% TRUE) &&
} else if (getOption('shiny.usecairo', TRUE) &&
nchar(system.file(package = "Cairo"))) {
pngfun <- Cairo::CairoPNG
} else {
@@ -42,15 +42,9 @@ plotPNG <- function(func, filename=tempfile(fileext='.png'),
}
pngfun(filename=filename, width=width, height=height, res=res, ...)
# Call plot.new() so that even if no plotting operations are performed at
# least we have a blank background. N.B. we need to set the margin to 0
# temporarily before plot.new() because when the plot size is small (e.g.
# 200x50), we will get an error "figure margin too large", which is triggered
# by plot.new() with the default (large) margin. However, this does not
# guarantee user's code in func() will not trigger the error -- they may have
# to set par(mar = smaller_value) before they draw base graphics.
op <- par(mar = rep(0, 4))
tryCatch(plot.new(), finally = par(op))
# Call plot.new() so that even if no plotting operations are performed
# at least we have a blank background
plot.new()
dv <- dev.cur()
tryCatch(shinyCallingHandlers(func()), finally = dev.off(dv))

View File

@@ -5,7 +5,7 @@ reactLogHandler <- function(req) {
if (!identical(req$PATH_INFO, '/reactlog'))
return(NULL)
if (!isTRUE(getOption('shiny.reactlog'))) {
if (!getOption('shiny.reactlog', FALSE)) {
return(NULL)
}

View File

@@ -281,7 +281,7 @@ HandlerManager <- setRefClass("HandlerManager",
createHttpuvApp = function() {
list(
onHeaders = function(req) {
maxSize <- getOption('shiny.maxRequestSize') %OR% (5 * 1024 * 1024)
maxSize <- getOption('shiny.maxRequestSize', 5 * 1024 * 1024)
if (maxSize <= 0)
return(NULL)
@@ -306,7 +306,7 @@ HandlerManager <- setRefClass("HandlerManager",
function (req) {
return(handlers$invoke(req))
},
getOption('shiny.sharedSecret')
getOption('shiny.sharedSecret', NULL)
),
onWSOpen = function(ws) {
return(wsHandlers$invoke(ws))
@@ -314,7 +314,7 @@ HandlerManager <- setRefClass("HandlerManager",
)
},
.httpServer = function(handler, sharedSecret) {
filter <- getOption('shiny.http.response.filter')
filter <- getOption('shiny.http.response.filter', NULL)
if (is.null(filter))
filter <- function(req, response) response
@@ -329,11 +329,11 @@ HandlerManager <- setRefClass("HandlerManager",
response <- handler(req)
if (is.null(response))
response <- httpResponse(404, content="<h1>Not Found</h1>")
if (inherits(response, "httpResponse")) {
headers <- as.list(response$headers)
headers$'Content-Type' <- response$content_type
response <- filter(req, response)
return(list(status=response$status,
body=response$content,

View File

@@ -98,7 +98,7 @@ ReactiveEnvironment <- setRefClass(
},
currentContext = function() {
if (is.null(.currentContext)) {
if (isTRUE(getOption('shiny.suppressMissingContextError'))) {
if (isTRUE(getOption('shiny.suppressMissingContextError', FALSE))) {
return(getDummyContext())
} else {
stop('Operation not allowed without an active reactive context. ',
@@ -138,7 +138,7 @@ ReactiveEnvironment <- setRefClass(
reactiveEnvironment <<- ReactiveEnvironment$new()
return(reactiveEnvironment)
}
})
})
# Causes any pending invalidations to run.
flushReact <- function() {

View File

@@ -75,7 +75,6 @@ createMockDomain <- function() {
#
## ------------------------------------------------------------------------
#' @name domains
#' @rdname domains
#' @export
getDefaultReactiveDomain <- function() {

View File

@@ -1,22 +1,112 @@
#' Run a Shiny application from https://gist.github.com
#'
#' Download and launch a Shiny application that is hosted on GitHub as a gist.
#'
#' @param gist The identifier of the gist. For example, if the gist is
#' https://gist.github.com/jcheng5/3239667, then \code{3239667},
#' \code{'3239667'}, and \code{'https://gist.github.com/jcheng5/3239667'}
#' are all valid values.
#' @param port The TCP port that the application should listen on. Defaults to
#' choosing a random port.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only.
#'
#' @examples
#' \dontrun{
#' runGist(3239667)
#' runGist("https://gist.github.com/jcheng5/3239667")
#'
#' # Old URL format without username
#' runGist("https://gist.github.com/3239667")
#' }
#'
#' @export
runGist <- function(gist,
port=NULL,
launch.browser=getOption('shiny.launch.browser',
interactive())) {
gistUrl <- if (is.numeric(gist) || grepl('^[0-9a-f]+$', gist)) {
sprintf('https://gist.github.com/%s/download', gist)
} else if(grepl('^https://gist.github.com/([^/]+/)?([0-9a-f]+)$', gist)) {
paste(gist, '/download', sep='')
} else {
stop('Unrecognized gist identifier format')
}
runUrl(gistUrl, filetype=".tar.gz", subdir=NULL, port=port,
launch.browser=launch.browser)
}
#' Run a Shiny application from a GitHub repository
#'
#' Download and launch a Shiny application that is hosted in a GitHub repository.
#'
#' @param repo Name of the repository
#' @param username GitHub username
#' @param ref Desired git reference. Could be a commit, tag, or branch
#' name. Defaults to \code{"master"}.
#' @param subdir A subdirectory in the repository that contains the app. By
#' default, this function will run an app from the top level of the repo, but
#' you can use a path such as `\code{"inst/shinyapp"}.
#' @param port The TCP port that the application should listen on. Defaults to
#' choosing a random port.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only.
#'
#' @examples
#' \dontrun{
#' runGitHub("shiny_example", "rstudio")
#'
#' # Can run an app from a subdirectory in the repo
#' runGitHub("shiny_example", "rstudio", subdir = "inst/shinyapp/")
#' }
#'
#' @export
runGitHub <- function(repo, username = getOption("github.user"),
ref = "master", subdir = NULL, port = NULL,
launch.browser = getOption('shiny.launch.browser', interactive())) {
if (is.null(ref)) {
stop("Must specify either a ref. ")
}
message("Downloading github repo(s) ",
paste(repo, ref, sep = "/", collapse = ", "),
" from ",
paste(username, collapse = ", "))
name <- paste(username, "-", repo, sep = "")
url <- paste("https://github.com/", username, "/", repo, "/archive/",
ref, ".tar.gz", sep = "")
runUrl(url, subdir=subdir, port=port, launch.browser=launch.browser)
}
#' Run a Shiny application from a URL
#'
#' \code{runUrl()} downloads and launches a Shiny application that is hosted at
#' a downloadable URL. The Shiny application must be saved in a .zip, .tar, or
#' .tar.gz file. The Shiny application files must be contained in the root
#' directory or a subdirectory in the archive. For example, the files might be
#' \code{myapp/server.r} and \code{myapp/ui.r}. The functions \code{runGitHub()}
#' and \code{runGist()} are based on \code{runUrl()}, using URL's from GitHub
#' (\url{https://github.com}) and GitHub gists (\url{https://gist.github.com}),
#' respectively.
#' Download and launch a Shiny application that is hosted at a downloadable
#' URL. The Shiny application must be saved in a .zip, .tar, or .tar.gz file.
#' The Shiny application files must be contained in a subdirectory in the
#' archive. For example, the files might be \code{myapp/server.r} and
#' \code{myapp/ui.r}.
#'
#' @param url URL of the application.
#' @param filetype The file type (\code{".zip"}, \code{".tar"}, or
#' \code{".tar.gz"}. Defaults to the file extension taken from the url.
#' @param subdir A subdirectory in the repository that contains the app. By
#' default, this function will run an app from the top level of the repo, but
#' you can use a path such as `\code{"inst/shinyapp"}.
#' @param ... Other arguments to be passed to \code{\link{runApp}()}, such as
#' \code{port} and \code{launch.browser}.
#' @export
#' @param port The TCP port that the application should listen on. Defaults to
#' choosing a random port.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only.
#'
#' @examples
#' \dontrun{
#' runUrl('https://github.com/rstudio/shiny_example/archive/master.tar.gz')
@@ -25,7 +115,10 @@
#' runUrl("https://github.com/rstudio/shiny_example/archive/master.zip",
#' subdir = "inst/shinyapp/")
#' }
runUrl <- function(url, filetype = NULL, subdir = NULL, ...) {
#'
#' @export
runUrl <- function(url, filetype = NULL, subdir = NULL, port = NULL,
launch.browser = getOption('shiny.launch.browser', interactive())) {
if (!is.null(subdir) && ".." %in% strsplit(subdir, '/')[[1]])
stop("'..' not allowed in subdir")
@@ -70,65 +163,5 @@ runUrl <- function(url, filetype = NULL, subdir = NULL, ...) {
if (!file_test('-d', appdir)) appdir <- dirname(appdir)
if (!is.null(subdir)) appdir <- file.path(appdir, subdir)
runApp(appdir, ...)
}
#' @rdname runUrl
#' @param gist The identifier of the gist. For example, if the gist is
#' https://gist.github.com/jcheng5/3239667, then \code{3239667},
#' \code{'3239667'}, and \code{'https://gist.github.com/jcheng5/3239667'} are
#' all valid values.
#' @export
#' @examples
#' \dontrun{
#' runGist(3239667)
#' runGist("https://gist.github.com/jcheng5/3239667")
#'
#' # Old URL format without username
#' runGist("https://gist.github.com/3239667")
#' }
#'
runGist <- function(gist, ...) {
gistUrl <- if (is.numeric(gist) || grepl('^[0-9a-f]+$', gist)) {
sprintf('https://gist.github.com/%s/download', gist)
} else if(grepl('^https://gist.github.com/([^/]+/)?([0-9a-f]+)$', gist)) {
paste(gist, '/download', sep='')
} else {
stop('Unrecognized gist identifier format')
}
runUrl(gistUrl, filetype=".tar.gz", ...)
}
#' @rdname runUrl
#' @param repo Name of the repository.
#' @param username GitHub username. If \code{repo} is of the form
#' \code{"username/repo"}, \code{username} will be taken from \code{repo}.
#' @param ref Desired git reference. Could be a commit, tag, or branch name.
#' Defaults to \code{"master"}.
#' @export
#' @examples
#' \dontrun{
#' runGitHub("shiny_example", "rstudio")
#' # or runGitHub("rstudio/shiny_example")
#'
#' # Can run an app from a subdirectory in the repo
#' runGitHub("shiny_example", "rstudio", subdir = "inst/shinyapp/")
#' }
runGitHub <- function(repo, username = getOption("github.user"),
ref = "master", subdir = NULL, ...) {
if (grepl('/', repo)) {
res <- strsplit(repo, '/')[[1]]
if (length(res) != 2) stop("'repo' must be of the form 'username/repo'")
username <- res[1]
repo <- res[2]
}
url <- paste("https://github.com/", username, "/", repo, "/archive/",
ref, ".tar.gz", sep = "")
runUrl(url, subdir=subdir, ...)
runApp(appdir, port=port, launch.browser=launch.browser)
}

View File

@@ -249,11 +249,8 @@ decodeMessage <- function(data) {
packBits(rawToBits(data[pos:(pos+3)]), type='integer')
}
if (readInt(1) != 0x01020202L) {
# use native encoding for the message
nativeData <- iconv(rawToChar(data), 'UTF-8')
return(fromJSON(nativeData, asText=TRUE, simplify=FALSE))
}
if (readInt(1) != 0x01020202L)
return(fromJSON(rawToChar(data), asText=TRUE, simplify=FALSE))
i <- 5
parts <- list()
@@ -281,7 +278,7 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
# This value, if non-NULL, must be present on all HTTP and WebSocket
# requests as the Shiny-Shared-Secret header or else access will be
# denied (403 response for HTTP, and instant close for websocket).
sharedSecret <- getOption('shiny.sharedSecret')
sharedSecret <- getOption('shiny.sharedSecret', NULL)
appHandlers <- list(
http = joinHandlers(c(
@@ -306,7 +303,7 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
if (is.character(msg))
msg <- charToRaw(msg)
if (isTRUE(getOption('shiny.trace'))) {
if (getOption('shiny.trace', FALSE)) {
if (binary)
message("RECV ", '$$binary data$$')
else
@@ -637,9 +634,7 @@ runApp <- function(appDir=getwd(),
if (is.character(appDir)) {
desc <- file.path.ci(appDir, "DESCRIPTION")
if (file.exists(desc)) {
con <- file(desc, encoding = checkEncoding(desc))
on.exit(close(con), add = TRUE)
settings <- read.dcf(con)
settings <- read.dcf(desc)
if ("DisplayMode" %in% colnames(settings)) {
mode <- settings[1,"DisplayMode"]
if (mode == "Showcase") {

View File

@@ -15,8 +15,7 @@ NULL
#' @name shiny-package
#' @aliases shiny
#' @docType package
#' @import htmltools httpuv xtable digest methods
#' @importFrom RJSONIO fromJSON
#' @import htmltools httpuv caTools RJSONIO xtable digest methods
NULL
createUniqueId <- function(bytes, prefix = "", suffix = "") {
@@ -32,10 +31,6 @@ createUniqueId <- function(bytes, prefix = "", suffix = "") {
})
}
toJSON <- function(x, ..., digits = getOption("shiny.json.digits", 16)) {
RJSONIO::toJSON(x, digits = digits, ...)
}
# Call the workerId func with no args to get the worker id, and with an arg to
# set it.
#
@@ -493,13 +488,11 @@ ShinySession <- setRefClass(
if (closed){
return()
}
if (isTRUE(getOption('shiny.trace')))
if (getOption('shiny.trace', FALSE))
message('SEND ',
gsub('(?m)base64,[a-zA-Z0-9+/=]+','[base64 data]',json,perl=TRUE))
# first convert to native encoding, then to UTF8, otherwise we may get the
# error in Chrome "WebSocket connection failed: Could not decode a text
# frame as UTF-8"
json <- enc2utf8(enc2native(json))
if (getOption('shiny.transcode.json', TRUE))
json <- iconv(json, to='UTF-8')
.websocket$send(json)
},
@@ -671,7 +664,7 @@ ShinySession <- setRefClass(
fileData <- readBin(file, 'raw', n=bytes)
if (isTRUE(.clientData$.values$allowDataUriScheme)) {
b64 <- rawToBase64(fileData)
b64 <- base64encode(fileData)
return(paste('data:', contentType, ';base64,', b64, sep=''))
} else {
return(saveFileUrl(name, fileData, contentType))

View File

@@ -33,7 +33,6 @@ renderPage <- function(ui, connection, showcase=0) {
deps <- c(
list(
htmlDependency("json2", "2014.02.04", c(href="shared"), script = "json2-min.js"),
htmlDependency("jquery", "1.11.0", c(href="shared"), script = "jquery.js"),
htmlDependency("shiny", packageVersion("shiny"), c(href="shared"),
script = "shiny.js", stylesheet = "shiny.css")
@@ -129,6 +128,6 @@ uiHttpHandler <- function(ui, path = "/") {
ui
renderPage(uiValue, textConn, showcaseMode)
html <- paste(textConnectionValue(textConn), collapse='\n')
return(httpResponse(200, content=enc2utf8(html)))
return(httpResponse(200, content=html))
}
}

View File

@@ -16,26 +16,23 @@ globalVariables('func')
#'
#' @export
markRenderFunction <- function(uiFunc, renderFunc) {
structure(renderFunc,
class = c("shiny.render.function", "function"),
outputFunc = uiFunc)
class(renderFunc) <- c("shiny.render.function", "function")
attr(renderFunc, "outputFunc") <- uiFunc
renderFunc
}
useRenderFunction <- function(renderFunc, inline = FALSE) {
useRenderFunction <- function(renderFunc) {
outputFunction <- attr(renderFunc, "outputFunc")
id <- createUniqueId(8, "out")
o <- getDefaultReactiveDomain()$output
if (!is.null(o))
o[[id]] <- renderFunc
if (is.logical(formals(outputFunction)[["inline"]])) {
outputFunction(id, inline = inline)
} else outputFunction(id)
return(outputFunction(id))
}
#' @export
#' @method as.tags shiny.render.function
as.tags.shiny.render.function <- function(x, ..., inline = FALSE) {
useRenderFunction(x, inline = inline)
#' @S3method as.tags shiny.render.function
as.tags.shiny.render.function <- function(x, ...) {
useRenderFunction(x)
}
#' Plot Output
@@ -50,13 +47,16 @@ as.tags.shiny.render.function <- function(x, ..., inline = FALSE) {
#' the output, see \code{\link{plotPNG}}.
#'
#' @param expr An expression that generates a plot.
#' @param width,height The width/height of the rendered plot, in pixels; or
#' \code{'auto'} to use the \code{offsetWidth}/\code{offsetHeight} of the HTML
#' element that is bound to this plot. You can also pass in a function that
#' returns the width/height in pixels or \code{'auto'}; in the body of the
#' function you may reference reactive values and functions. When rendering an
#' inline plot, you must provide numeric values (in pixels) to both
#' \code{width} and \code{height}.
#' @param width The width of the rendered plot, in pixels; or \code{'auto'} to
#' use the \code{offsetWidth} of the HTML element that is bound to this plot.
#' You can also pass in a function that returns the width in pixels or
#' \code{'auto'}; in the body of the function you may reference reactive
#' values and functions.
#' @param height The height of the rendered plot, in pixels; or \code{'auto'} to
#' use the \code{offsetHeight} of the HTML element that is bound to this plot.
#' You can also pass in a function that returns the width in pixels or
#' \code{'auto'}; in the body of the function you may reference reactive
#' values and functions.
#' @param res Resolution of resulting plot, in pixels per inch. This value is
#' passed to \code{\link{png}}. Note that this affects the resolution of PNG
#' rendering in R; it won't change the actual ppi of the browser.
@@ -93,8 +93,10 @@ renderPlot <- function(expr, width='auto', height='auto', res=72, ...,
# div needs to adapt to the height of renderPlot. By default, plotOutput
# sets the height to 400px, so to make it adapt we need to override it
# with NULL.
outputFunc <- plotOutput
if (!identical(height, 'auto')) formals(outputFunc)['height'] <- list(NULL)
outputFunc <- if (identical(height, 'auto'))
plotOutput
else
function(outputId) plotOutput(outputId, height = NULL)
return(markRenderFunction(outputFunc, function(shinysession, name, ...) {
if (!is.null(widthWrapper))
@@ -317,7 +319,7 @@ renderTable <- function(expr, ..., env=parent.frame(), quoted=FALSE, func=NULL)
}
markRenderFunction(tableOutput, function() {
classNames <- getOption('shiny.table.class') %OR% 'data table table-bordered table-condensed'
classNames <- getOption('shiny.table.class', 'data table table-bordered table-condensed')
data <- func()
if (is.null(data) || identical(data, data.frame()))

View File

@@ -50,7 +50,7 @@ showcaseHead <- function() {
href="shared/shiny-showcase.css"),
if (file.exists(mdfile))
script(type="text/markdown", id="showcase-markdown-content",
paste(readUTF8(mdfile), collapse="\n"))
paste(readLines(mdfile, warn = FALSE), collapse="\n"))
else ""
))
@@ -106,7 +106,8 @@ showcaseCodeTabs <- function(codeLicense) {
# we need to prevent the indentation of <code> ... </code>
HTML(format(tags$code(
class="language-r",
paste(readUTF8(file.path.ci(getwd(), rFile)), collapse="\n")
paste(readLines(file.path.ci(getwd(), rFile), warn=FALSE),
collapse="\n")
), indent = FALSE))))
})),
codeLicense))
@@ -120,9 +121,7 @@ showcaseAppInfo <- function() {
readmemd <- file.path.ci(getwd(), "Readme.md")
hasReadme <- file.exists(readmemd)
if (hasDesc) {
con <- textConnection(readUTF8(descfile))
on.exit(close(con), add = TRUE)
desc <- read.dcf(con)
desc <- read.dcf(descfile)
}
with(tags,
div(class="container-fluid shiny-code-container well",

View File

@@ -141,7 +141,7 @@ untar2 <- function(tarfile, files = NULL, list = FALSE, exdir = ".")
warning(gettextf("failed to copy %s to %s", sQuote(name2), sQuote(name)), domain = NA)
}
} else {
if(isWindows()) {
if(.Platform$OS.type == "windows") {
## this will not work for links to dirs
from <- file.path(dirname(name), name2)
if (!file.copy(from, name))

View File

@@ -118,7 +118,7 @@ updateSliderInput <- updateTextInput
#' }
#' @export
updateDateInput <- function(session, inputId, label = NULL, value = NULL,
min = NULL, max = NULL) {
min = NULL, max = NULL) {
# If value is a date object, convert it to a string with yyyy-mm-dd format
# Same for min and max
@@ -163,8 +163,8 @@ updateDateInput <- function(session, inputId, label = NULL, value = NULL,
#' }
#' @export
updateDateRangeInput <- function(session, inputId, label = NULL,
start = NULL, end = NULL, min = NULL,
max = NULL) {
start = NULL, end = NULL, min = NULL, max = NULL) {
# Make sure start and end are strings, not date objects. This is for
# consistency across different locales.
if (inherits(start, "Date")) start <- format(start, '%Y-%m-%d')
@@ -256,28 +256,13 @@ updateNumericInput <- function(session, inputId, label = NULL, value = NULL,
session$sendInputMessage(inputId, message)
}
updateInputOptions <- function(session, inputId, label = NULL, choices = NULL,
selected = NULL, inline = FALSE,
type = 'checkbox') {
choices <- choicesWithNames(choices)
if (!is.null(selected))
selected <- validateSelected(selected, choices, inputId)
options <- if (length(choices))
format(tagList(
generateOptions(inputId, choices, selected, inline, type = type)
))
message <- dropNulls(list(label = label, options = options, value = selected))
session$sendInputMessage(inputId, message)
}
#' Change the value of a checkbox group input on the client
#'
#' @template update-input
#' @inheritParams checkboxGroupInput
#' @param choices A named vector or named list of options. For each item, the
#' name will be used as the label, and the value will be used as the value.
#' @param selected A vector or list of options (values) which will be selected.
#'
#' @seealso \code{\link{checkboxGroupInput}}
#'
@@ -310,16 +295,27 @@ updateInputOptions <- function(session, inputId, label = NULL, choices = NULL,
#' }
#' @export
updateCheckboxGroupInput <- function(session, inputId, label = NULL,
choices = NULL, selected = NULL,
inline = FALSE) {
updateInputOptions(session, inputId, label, choices, selected, inline)
choices = NULL, selected = NULL) {
choices <- choicesWithNames(choices)
if (!is.null(selected))
selected <- validateSelected(selected, choices, inputId)
options <- if (length(choices))
columnToRowData(list(value = choices, label = names(choices)))
message <- dropNulls(list(label = label, options = options, value = selected))
session$sendInputMessage(inputId, message)
}
#' Change the value of a radio input on the client
#'
#' @template update-input
#' @inheritParams radioButtons
#' @param choices A named vector or named list of options. For each item, the
#' name will be used as the label, and the value will be used as the value.
#' @param selected A vector or list of options (values) which will be selected.
#'
#' @seealso \code{\link{radioButtons}}
#'
@@ -349,18 +345,15 @@ updateCheckboxGroupInput <- function(session, inputId, label = NULL,
#' })
#' }
#' @export
updateRadioButtons <- function(session, inputId, label = NULL, choices = NULL,
selected = NULL, inline = FALSE) {
# you must select at least one radio button
if (is.null(selected) && !is.null(choices)) selected <- choices[[1]]
updateInputOptions(session, inputId, label, choices, selected, inline, type = 'radio')
}
updateRadioButtons <- updateCheckboxGroupInput
#' Change the value of a select input on the client
#'
#' @template update-input
#' @inheritParams selectInput
#' @param choices A named vector or named list of options. For each item, the
#' name will be used as the label, and the value will be used as the value.
#' @param selected A vector or list of options (values) which will be selected.
#'
#' @seealso \code{\link{selectInput}}
#'
@@ -393,26 +386,19 @@ updateRadioButtons <- function(session, inputId, label = NULL, choices = NULL,
#' })
#' }
#' @export
updateSelectInput <- function(session, inputId, label = NULL, choices = NULL,
selected = NULL) {
choices <- choicesWithNames(choices)
if (!is.null(selected))
selected <- validateSelected(selected, choices, inputId)
options <- if (length(choices)) selectOptions(choices, selected)
message <- dropNulls(list(label = label, options = options, value = selected))
session$sendInputMessage(inputId, message)
}
updateSelectInput <- updateCheckboxGroupInput
#' @rdname updateSelectInput
#' @inheritParams selectizeInput
#' @param options a list of options (see \code{\link{selectizeInput}})
#' @param server whether to store \code{choices} on the server side, and load
#' the select options dynamically on searching, instead of writing all
#' \code{choices} into the page at once (i.e., only use the client-side
#' version of \pkg{selectize.js})
#' @export
updateSelectizeInput <- function(session, inputId, label = NULL, choices = NULL,
selected = NULL, options = list(),
server = FALSE) {
updateSelectizeInput <- function(
session, inputId, label = NULL, choices = NULL, selected = NULL,
options = list(), server = FALSE
) {
if (length(options)) {
res <- checkAsIs(options)
cfg <- tags$script(
@@ -421,7 +407,7 @@ updateSelectizeInput <- function(session, inputId, label = NULL, choices = NULL,
`data-eval` = if (length(res$eval)) HTML(toJSON(res$eval)),
HTML(toJSON(res$options))
)
session$sendInputMessage(inputId, list(config = as.character(cfg)))
session$sendInputMessage(inputId, list(newOptions = as.character(cfg)))
}
if (!server) {
return(updateSelectInput(session, inputId, label, choices, selected))
@@ -455,8 +441,8 @@ selectizeJSON <- function(data, req) {
# convert a single vector to a data frame so it returns {label: , value: }
# later in JSON; other objects return arbitrary JSON {x: , y: , foo: , ...}
data <- if (is.atomic(data)) {
data.frame(label = names(choicesWithNames(data)), value = data,
stringsAsFactors = FALSE)
data <- choicesWithNames(data)
data.frame(label = names(data), value = data, stringsAsFactors = FALSE)
} else as.data.frame(data, stringsAsFactors = FALSE)
# start searching for keywords in all specified columns

114
R/utils.R
View File

@@ -77,22 +77,11 @@ withPrivateSeed <- function(expr) {
.globals$ownSeed, unset=is.null(.globals$ownSeed), {
tryCatch({
expr
}, finally = {
.globals$ownSeed <- getExists('.Random.seed', 'numeric', globalenv())
})
}, finally = {.globals$ownSeed <- .Random.seed})
}
)
}
# a homemade version of set.seed(NULL) for backward compatibility with R 2.15.x
reinitializeSeed <- if (getRversion() >= '3.0.0') {
function() set.seed(NULL)
} else function() {
if (exists('.Random.seed', globalenv()))
rm(list = '.Random.seed', pos = globalenv())
stats::runif(1) # generate any random numbers so R can reinitialize the seed
}
# Version of runif that runs with private seed
p_runif <- function(...) {
withPrivateSeed(runif(...))
@@ -185,7 +174,7 @@ resolve <- function(dir, relpath) {
abs.path <- normalizePath(abs.path, winslash='/', mustWork=TRUE)
dir <- normalizePath(dir, winslash='/', mustWork=TRUE)
# trim the possible trailing slash under Windows (#306)
if (isWindows()) dir <- sub('/$', '', dir)
if (.Platform$OS.type == 'windows') dir <- sub('/$', '', dir)
if (nchar(abs.path) <= nchar(dir) + 1)
return(NULL)
if (substr(abs.path, 1, nchar(dir)) != dir ||
@@ -195,8 +184,6 @@ resolve <- function(dir, relpath) {
return(abs.path)
}
isWindows <- function() .Platform$OS.type == 'windows'
# This is a wrapper for download.file and has the same interface.
# The only difference is that, if the protocol is https, it changes the
# download settings, depending on platform.
@@ -205,7 +192,7 @@ download <- function(url, ...) {
if (grepl('^https?://', url)) {
# If Windows, call setInternet2, then use download.file with defaults.
if (isWindows()) {
if (.Platform$OS.type == "windows") {
# If we directly use setInternet2, R CMD CHECK gives a Note on Mac/Linux
mySI2 <- `::`(utils, 'setInternet2')
# Store initial settings
@@ -489,7 +476,7 @@ shinyCallingHandlers <- function(expr) {
shinyDeprecated <- function(new=NULL, msg=NULL,
old=as.character(sys.call(sys.parent()))[1L]) {
if (getOption("shiny.deprecation.messages") %OR% TRUE == FALSE)
if (getOption("shiny.deprecation.messages", default=TRUE) == FALSE)
return(invisible())
if (is.null(msg)) {
@@ -738,6 +725,18 @@ cachedFuncWithFile <- function(dir, file, func, case.sensitive = FALSE) {
}
}
# Returns a function that sources the file and caches the result for subsequent
# calls, unless the file's mtime changes.
cachedSource <- function(dir, file, case.sensitive = FALSE) {
dir <- normalizePath(dir, mustWork=TRUE)
cachedFuncWithFile(dir, file, function(fname, ...) {
if (file.exists(fname))
return(source(fname, ...))
else
return(NULL)
})
}
# turn column-based data to row-based data (mainly for JSON), e.g. data.frame(x
# = 1:10, y = 10:1) ==> list(list(x = 1, y = 10), list(x = 2, y = 9), ...)
columnToRowData <- function(data) {
@@ -898,84 +897,3 @@ stopWithCondition <- function(class, message) {
)
stop(cond)
}
#' Collect information about the Shiny Server environment
#'
#' This function returns the information about the current Shiny Server, such as
#' its version, and whether it is the open source edition or professional
#' edition. If the app is not served through the Shiny Server, this function
#' just returns \code{list(shinyServer = FALSE)}.
#' @export
#' @return A list of the Shiny Server information.
serverInfo <- function() {
.globals$serverInfo
}
.globals$serverInfo <- list(shinyServer = FALSE)
setServerInfo <- function(...) {
infoOld <- serverInfo()
infoNew <- list(...)
infoOld[names(infoNew)] <- infoNew
.globals$serverInfo <- infoOld
}
# see if the file can be read as UTF-8 on Windows, and converted from UTF-8 to
# native encoding; if the conversion fails, it will produce NA's in the results
checkEncoding <- function(file) {
# skip *nix because its locale is normally UTF-8 based (e.g. en_US.UTF-8), and
# *nix users have to make a conscious effort to save a file with an encoding
# that is not UTF-8; if they choose to do so, we cannot do much about it
# except sitting back and seeing them punished after they choose to escape a
# world of consistency (falling back to getOption('encoding') will not help
# because native.enc is also normally UTF-8 based on *nix)
if (!isWindows()) return('UTF-8')
# an empty file?
size <- file.info(file)[, 'size']
if (size == 0) return('UTF-8')
x <- readLines(file, encoding = 'UTF-8', warn = FALSE)
# if conversion is successful and there are no embedded nul's, use UTF-8
if (!any(is.na(iconv(x, 'UTF-8'))) &&
!any(readBin(file, 'raw', size) == as.raw(0))) return('UTF-8')
# check if there is a BOM character: this is also skipped on *nix, because R
# on *nix simply ignores this meaningless character if present, but it hurts
# on Windows
if (identical(charToRaw(readChar(file, 3L, TRUE)), charToRaw('\UFEFF'))) {
warning('You should not include the Byte Order Mark (BOM) in ', file, '. ',
'Please re-save it in UTF-8 without BOM. See ',
'http://shiny.rstudio.com/articles/unicode.html for more info.')
if (getRversion() < '3.0.0')
stop('R does not support UTF-8-BOM before 3.0.0. Please upgrade R.')
return('UTF-8-BOM')
}
enc <- getOption('encoding')
msg <- c(sprintf('The file "%s" is not encoded in UTF-8. ', file),
'Please convert its encoding to UTF-8 ',
'(e.g. use the menu `File -> Save with Encoding` in RStudio). ',
'See http://shiny.rstudio.com/articles/unicode.html for more info.')
if (enc == 'UTF-8') stop(msg)
# if you publish the app to ShinyApps.io, you will be in trouble
warning(c(msg, ' Falling back to the encoding "', enc, '".'))
enc
}
# try to read a file using UTF-8 (fall back to getOption('encoding') in case of
# failure, which defaults to native.enc, i.e. native encoding)
readUTF8 <- function(file) {
enc <- checkEncoding(file)
# readLines() does not support UTF-8-BOM directly; has to go through file()
if (enc == 'UTF-8-BOM') {
file <- base::file(file, encoding = enc)
on.exit(close(file), add = TRUE)
}
x <- readLines(file, encoding = enc, warn = FALSE)
enc2native(x)
}
# similarly, try to source() a file with UTF-8
sourceUTF8 <- function(file, ...) {
source(file, ..., keep.source = TRUE, encoding = checkEncoding(file))
}

View File

@@ -1,6 +1,6 @@
# Shiny
[![Build Status](https://travis-ci.org/rstudio/shiny.svg?branch=master)](https://travis-ci.org/rstudio/shiny)
[![Build Status](https://travis-ci.org/rstudio/shiny.png)](https://travis-ci.org/rstudio/shiny)
Shiny is a new package from RStudio that makes it incredibly easy to build interactive web applications with R.

View File

@@ -127,6 +127,8 @@ sd_section("Running",
c(
"runApp",
"runExample",
"runGist",
"runGitHub",
"runUrl",
"stopApp"
)
@@ -150,8 +152,7 @@ sd_section("Utility functions",
"parseQueryString",
"plotPNG",
"repeatable",
"shinyDeprecated",
"serverInfo"
"shinyDeprecated"
)
)
sd_section("Embedding",

View File

@@ -43,110 +43,3 @@ test_that("Repeated names for selectInput and radioButtons choices", {
expect_equal(choices[[2]][[3]]$children[[1]]$attribs$value, 'x3')
expect_equal(choices[[2]][[3]]$children[[1]]$attribs$checked, NULL)
})
test_that("Choices are correctly assigned names", {
# Unnamed vector
expect_identical(
choicesWithNames(c("a","b","3")),
list(a="a", b="b", "3"="3")
)
# Unnamed list
expect_identical(
choicesWithNames(list("a","b",3)),
list(a="a", b="b", "3"=3)
)
# Vector, with some named, some not
expect_identical(
choicesWithNames(c(A="a", "b", C="3", "4")),
list(A="a", "b"="b", C="3", "4"="4")
)
# List, with some named, some not
expect_identical(
choicesWithNames(list(A="a", "b", C=3, 4)),
list(A="a", "b"="b", C=3, "4"=4)
)
# List, named, with a sub-vector
expect_identical(
choicesWithNames(list(A="a", B="b", C=c("d", "e"))),
list(A="a", B="b", C=list(d="d", e="e"))
)
# List, named, with sublist
expect_identical(
choicesWithNames(list(A="a", B="b", C=list("d", "e"))),
list(A="a", B="b", C=list(d="d", e="e"))
)
# List, named, with a named sub-vector of length 1
expect_identical(
choicesWithNames(list(A="a", B="b", C=c(D="d"))),
list(A="a", B="b", C=list(D="d"))
)
# List, some named, with sublist
expect_identical(
choicesWithNames(list(A="a", "b", C=list("d", E="e"))),
list(A="a", b="b", C=list(d="d", E="e"))
)
# Deeper nesting
expect_identical(
choicesWithNames(list(A="a", "b", C=list(D=list("e", "f"), G=c(H="h", "i")))),
list(A="a", b="b", C=list(D=list(e="e", f="f"), G=list(H="h", i="i")))
)
# Error when sublist is unnamed
expect_error(choicesWithNames(list(A="a", "b", list(1,2))))
})
test_that("selectOptions returns correct HTML", {
# None selected
expect_identical(
selectOptions(choicesWithNames(list("a", "b")), list()),
HTML("<option value=\"a\">a</option>\n<option value=\"b\">b</option>")
)
# One selected
expect_identical(
selectOptions(choicesWithNames(list("a", "b")), "a"),
HTML("<option value=\"a\" selected>a</option>\n<option value=\"b\">b</option>")
)
# One selected, with named items
expect_identical(
selectOptions(choicesWithNames(list(A="a", B="b")), "a"),
HTML("<option value=\"a\" selected>A</option>\n<option value=\"b\">B</option>")
)
# Two selected, with optgroup
expect_identical(
selectOptions(choicesWithNames(list("a", B=list("c", D="d"))), c("a", "d")),
HTML("<option value=\"a\" selected>a</option>\n<optgroup label=\"B\">\n<option value=\"c\">c</option>\n<option value=\"d\" selected>D</option>\n</optgroup>")
)
# Escape HTML in strings
expect_identical(
selectOptions(choicesWithNames(list("<A>"="a", B="b")), "a"),
HTML("<option value=\"a\" selected>&lt;A&gt;</option>\n<option value=\"b\">B</option>")
)
})
test_that("selectInput selects items by default", {
# None specified as selected (defaults to first)
expect_true(grepl(
'<option value="a" selected>',
selectInput('x', 'x', list("a", "b"))
))
# Nested list (optgroup)
expect_true(grepl(
'<option value="a" selected>',
selectInput('x', 'x', list(A=list("a", "b"), "c"))
))
# Nothing selected when choices=NULL
expect_identical(
'<select id="x"></select>',
format(selectInput('x', NULL, NULL, selectize = FALSE))
)
# None specified as selected. With multiple=TRUE, none selected by default.
expect_true(grepl(
'<option value="a">',
selectInput('x', 'x', list("a", "b"), multiple = TRUE)
))
})

View File

@@ -6,7 +6,7 @@ test_that("All man pages have an entry in staticdocs/index.r", {
return()
}
# Known not to be indexed
known_unindexed <- c("shiny-package", "knitr_methods", "knitr_methods_htmltools")
known_unindexed <- c("shiny-package", "knitr_methods")
indexed_topics <- local({
result <- character(0)

View File

@@ -21,10 +21,6 @@ test_that("Setting process-wide seed doesn't affect private randomness", {
test_that("Resetting private seed doesn't result in dupes", {
.globals$ownSeed <- NULL
id3 <- createUniqueId(4)
# Make sure we let enough time pass that reinitializing the seed is
# going to result in a different value. This is especially required
# on Windows.
Sys.sleep(1)
set.seed(0)
.globals$ownSeed <- NULL
id4 <- createUniqueId(4)

View File

@@ -1,22 +0,0 @@
("object"!=typeof JSON||JSON.stringify("\uf977").length>3)&&(JSON={}),function(){"use strict"
function f(t){return 10>t?"0"+t:t}function quote(t){return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t]
return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var n,r,o,f,u,p=gap,a=e[t]
switch(a&&"object"==typeof a&&"function"==typeof a.toJSON&&(a=a.toJSON(t)),"function"==typeof rep&&(a=rep.call(e,t,a)),typeof a){case"string":return quote(a)
case"number":return isFinite(a)?a+"":"null"
case"boolean":case"null":return a+""
case"object":if(!a)return"null"
if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(a)){for(f=a.length,n=0;f>n;n+=1)u[n]=str(n,a)||"null"
return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+p+"]":"["+u.join(",")+"]",gap=p,o}if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep[n]&&(r=rep[n],o=str(r,a),o&&u.push(quote(r)+(gap?": ":":")+o))
else for(r in a)Object.prototype.hasOwnProperty.call(a,r)&&(o=str(r,a),o&&u.push(quote(r)+(gap?": ":":")+o))
return o=0===u.length?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+p+"}":"{"+u.join(",")+"}",gap=p,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()})
var cx,escapable,gap,indent,meta,rep
"function"!=typeof JSON.stringify&&(escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,n){var r
if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" "
else"string"==typeof n&&(indent=n)
if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw Error("JSON.stringify")
return str("",{"":t})}),"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t[e]
if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(r=walk(o,n),void 0!==r?o[n]=r:delete o[n])
return reviver.call(t,e,o)}var j
if(text+="",cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j
throw new SyntaxError("JSON.parse")})}()

File diff suppressed because one or more lines are too long

View File

@@ -85,11 +85,6 @@
var code = document.getElementById(srcfile.replace(/\./g, "_") + "_code");
var start = findTextPoint(code, ref[0], ref[4]);
var end = findTextPoint(code, ref[2], ref[5]);
// If the insertion point can't be found, bail out now
if (start.element === null || end.element === null)
return;
var range = document.createRange();
// If the text points are inside different <SPAN>s, we may not be able to
// surround them without breaking apart the elements to keep the DOM tree

View File

@@ -34,14 +34,9 @@
var x;
if (el.currentStyle)
x = el.currentStyle[styleProp];
else if (window.getComputedStyle) {
// getComputedStyle can return null when we're inside a hidden iframe on
// Firefox; don't attempt to retrieve style props in this case.
// https://bugzilla.mozilla.org/show_bug.cgi?id=548397
var style = document.defaultView.getComputedStyle(el, null);
if (style)
x = style.getPropertyValue(styleProp);
}
else if (window.getComputedStyle)
x = document.defaultView.getComputedStyle(el, null)
.getPropertyValue(styleProp);
return x;
}
@@ -2096,20 +2091,37 @@
// This will replace all the options
if (data.hasOwnProperty('options')) {
selectize = this._selectize(el);
// Must destroy selectize before appending new options, otherwise
// selectize will restore the original select
if (selectize) selectize.destroy();
// Clear existing options and add each new one
$el.empty().append(data.options);
this._selectize(el);
$el.empty();
selectize = this._selectize(el);
if (selectize !== undefined) {
selectize.clearOptions();
// Selectize.js doesn't maintain insertion order on Chrome on Mac
// with >10 items if inserted using addOption (versus being present
// in the DOM at selectize() time). Putting $order on each option
// makes it work.
$.each(data.options, function(i, opt) {
opt.$order = i;
});
selectize.addOption(data.options);
}
for (var i = 0; i < data.options.length; i++) {
var in_opt = data.options[i];
var $newopt = $('<option/>', {
value: in_opt.value,
text: in_opt.label
});
$el.append($newopt);
}
}
// re-initialize selectize
if (data.hasOwnProperty('config')) {
if (data.hasOwnProperty('newOptions')) {
$el.parent()
.find('script[data-for="' + $escape(el.id) + '"]')
.replaceWith(data.config);
.replaceWith(data.newOptions);
this._selectize(el, true);
}
@@ -2241,7 +2253,22 @@
if (data.hasOwnProperty('options')) {
// Clear existing options and add each new one
$el.find('label.radio').remove();
$el.append(data.options);
for (var i = 0; i < data.options.length; i++) {
var in_opt = data.options[i];
var $newopt = $('<label class="radio"/>');
var $radio = $('<input/>', {
type: "radio",
name: el.id,
id: el.id + (i+1).toString(),
value: in_opt.value
});
$newopt.append($radio);
$newopt.append('<span>' + in_opt.label + '</span>');
$el.append($newopt);
}
}
if (data.hasOwnProperty('value'))
@@ -2351,7 +2378,22 @@
if (data.hasOwnProperty('options')) {
// Clear existing options and add each new one
$el.find('label.checkbox').remove();
$el.append(data.options);
for (var i = 0; i < data.options.length; i++) {
var in_opt = data.options[i];
var $newopt = $('<label class="checkbox"/>');
var $checkbox = $('<input/>', {
type: "checkbox",
name: el.id,
id: el.id + (i+1).toString(),
value: in_opt.value
});
$newopt.append($checkbox);
$newopt.append('<span>' + in_opt.label + '</span>');
$el.append($newopt);
}
}
if (data.hasOwnProperty('value'))

View File

@@ -3,7 +3,7 @@
\alias{checkboxGroupInput}
\title{Checkbox Group Input Control}
\usage{
checkboxGroupInput(inputId, label, choices, selected = NULL, inline = FALSE)
checkboxGroupInput(inputId, label, choices, selected = NULL)
}
\arguments{
\item{inputId}{Input variable to assign the control's value to.}
@@ -14,8 +14,6 @@ checkboxGroupInput(inputId, label, choices, selected = NULL, inline = FALSE)
are named then that name rather than the value is displayed to the user.}
\item{selected}{The values that should be initially selected, if any.}
\item{inline}{If \code{TRUE}, render the choices inline (i.e. horizontally)}
}
\value{
A list of HTML elements that can be added to a UI definition.

View File

@@ -23,13 +23,6 @@ example, if you have an input with an id of \code{foo}, then you can use
\code{input.foo} to read its value. (Be sure not to modify the input/output
objects, as this may cause unpredictable behavior.)
}
\note{
You are not recommended to use special JavaScript characters such as a
period \code{.} in the input id's, but if you do use them anyway, for
example, \code{inputId = "foo.bar"}, you will have to use
\code{input["foo.bar"]} instead of \code{input.foo.bar} to read the input
value.
}
\examples{
sidebarPanel(
selectInput(

View File

@@ -1,5 +1,5 @@
% Generated by roxygen2 (4.0.1): do not edit by hand
\name{domains}
\name{getDefaultReactiveDomain}
\alias{domains}
\alias{getDefaultReactiveDomain}
\alias{onReactiveDomainEnded}

View File

@@ -27,5 +27,7 @@ flowLayout(
}
\seealso{
\code{\link{verticalLayout}}
#'
}

View File

@@ -4,15 +4,12 @@
\alias{uiOutput}
\title{Create an HTML output element}
\usage{
htmlOutput(outputId, inline = FALSE)
htmlOutput(outputId)
uiOutput(outputId, inline = FALSE)
uiOutput(outputId)
}
\arguments{
\item{outputId}{output variable to read the value from}
\item{inline}{use an inline (\code{span()}) or block container (\code{div()})
for the output}
}
\value{
An HTML output element that can be included in a panel

View File

@@ -3,7 +3,7 @@
\alias{imageOutput}
\title{Create a image output element}
\usage{
imageOutput(outputId, width = "100\%", height = "400px", inline = FALSE)
imageOutput(outputId, width = "100\%", height = "400px")
}
\arguments{
\item{outputId}{output variable to read the image from}
@@ -13,9 +13,6 @@ imageOutput(outputId, width = "100\%", height = "400px", inline = FALSE)
string and have \code{"px"} appended.}
\item{height}{Image height}
\item{inline}{use an inline (\code{span()}) or block container (\code{div()})
for the output}
}
\value{
An image output element that can be included in a panel

View File

@@ -7,14 +7,12 @@
\usage{
knit_print.shiny.appobj(x, ...)
knit_print.shiny.render.function(x, ..., inline = FALSE)
knit_print.shiny.render.function(x, ...)
}
\arguments{
\item{x}{Object to knit_print}
\item{...}{Additional knit_print arguments}
\item{inline}{Whether the object is printed inline.}
}
\description{
These S3 methods are necessary to help Shiny applications and UI chunks embed

View File

@@ -1,22 +0,0 @@
\name{knit_print.html}
\alias{knit_print.html}
\alias{knit_print.shiny.tag}
\alias{knit_print.shiny.tag.list}
\title{Knitr S3 methods}
\usage{
knit_print.shiny.tag(x, ...)
knit_print.html(x, ...)
knit_print.shiny.tag.list(x, ...)
}
\arguments{
\item{x}{Object to knit_print}
\item{...}{Additional knit_print arguments}
}
\description{
These S3 methods are necessary to allow HTML tags to print themselves in
knitr/rmarkdown documents.
}

View File

@@ -6,7 +6,7 @@
\usage{
navbarPage(title, ..., id = NULL, header = NULL, footer = NULL,
inverse = FALSE, collapsable = FALSE, fluid = TRUE, responsive = TRUE,
theme = NULL, windowTitle = title)
theme = NULL)
navbarMenu(title, ..., icon = NULL)
}
@@ -43,9 +43,6 @@ and resize page elements based on the size of the viewing device)}
www directory). For example, to use the theme located at
\code{www/bootstrap.css} you would use \code{theme = "bootstrap.css"}.}
\item{windowTitle}{The title that should be displayed by the browser window.
Useful if \code{title} is not a string.}
\item{icon}{Optional icon to appear on a \code{navbarMenu} tab.}
}
\value{

View File

@@ -5,30 +5,29 @@
\usage{
plotOutput(outputId, width = "100\%", height = "400px", clickId = NULL,
hoverId = NULL, hoverDelay = 300, hoverDelayType = c("debounce",
"throttle"), inline = FALSE)
"throttle"))
}
\arguments{
\item{outputId}{output variable to read the plot from}
\item{width,height}{Plot width/height. Must be a valid CSS unit (like
\code{"100\%"}, \code{"400px"}, \code{"auto"}) or a number, which will be
coerced to a string and have \code{"px"} appended. These two arguments are
ignored when \code{inline = TRUE}, in which case the width/height of a plot
must be specified in \code{renderPlot()}.}
\item{width}{Plot width. Must be a valid CSS unit (like \code{"100\%"},
\code{"400px"}, \code{"auto"}) or a number, which will be coerced to a
string and have \code{"px"} appended.}
\item{height}{Plot height}
\item{clickId}{If not \code{NULL}, the plot will send coordinates to the
server whenever it is clicked. This information will be accessible on the
\code{input} object using \code{input$}\emph{\code{clickId}}. The value
will be a named list or vector with \code{x} and \code{y} elements
indicating the mouse position in user units.}
\code{input} object using \code{input$}\emph{\code{clickId}}. The value will be a
named list or vector with \code{x} and \code{y} elements indicating the
mouse position in user units.}
\item{hoverId}{If not \code{NULL}, the plot will send coordinates to the
server whenever the mouse pauses on the plot for more than the number of
milliseconds determined by \code{hoverTimeout}. This information will be
accessible on the \code{input} object using
\code{input$}\emph{\code{clickId}}. The value will be \code{NULL} if the
user is not hovering, and a named list or vector with \code{x} and \code{y}
elements indicating the mouse position in user units.}
The value will be \code{NULL} if the user is not hovering, and a named
list or vector with \code{x} and \code{y} elements indicating the mouse
position in user units.}
\item{hoverDelay}{The delay for hovering, in milliseconds.}
@@ -37,9 +36,6 @@ events. Use \code{"throttle"} to limit the number of hover events to one
every \code{hoverDelay} milliseconds. Use \code{"debounce"} to suspend
events while the cursor is moving, and wait until the cursor has been at
rest for \code{hoverDelay} milliseconds before sending an event.}
\item{inline}{use an inline (\code{span()}) or block container (\code{div()})
for the output}
}
\value{
A plot output element that can be included in a panel
@@ -47,12 +43,6 @@ A plot output element that can be included in a panel
\description{
Render a \link{renderPlot} within an application page.
}
\note{
The arguments \code{clickId} and \code{hoverId} only work for R base
graphics (see the \pkg{\link{graphics}} package). They do not work for
\pkg{\link[grid:grid-package]{grid}}-based graphics, such as \pkg{ggplot2},
\pkg{lattice}, and so on.
}
\examples{
# Show a plot of the generated distribution
mainPanel(

View File

@@ -3,7 +3,7 @@
\alias{radioButtons}
\title{Create radio buttons}
\usage{
radioButtons(inputId, label, choices, selected = NULL, inline = FALSE)
radioButtons(inputId, label, choices, selected = NULL)
}
\arguments{
\item{inputId}{Input variable to assign the control's value to}
@@ -15,8 +15,6 @@ named then that name rather than the value is displayed to the user)}
\item{selected}{The initially selected value (if not specified then
defaults to the first value)}
\item{inline}{If \code{TRUE}, render the choices inline (i.e. horizontally)}
}
\value{
A set of radio buttons that can be added to a UI definition.

View File

@@ -9,13 +9,17 @@ renderPlot(expr, width = "auto", height = "auto", res = 72, ...,
\arguments{
\item{expr}{An expression that generates a plot.}
\item{width,height}{The width/height of the rendered plot, in pixels; or
\code{'auto'} to use the \code{offsetWidth}/\code{offsetHeight} of the HTML
element that is bound to this plot. You can also pass in a function that
returns the width/height in pixels or \code{'auto'}; in the body of the
function you may reference reactive values and functions. When rendering an
inline plot, you must provide numeric values (in pixels) to both
\code{width} and \code{height}.}
\item{width}{The width of the rendered plot, in pixels; or \code{'auto'} to
use the \code{offsetWidth} of the HTML element that is bound to this plot.
You can also pass in a function that returns the width in pixels or
\code{'auto'}; in the body of the function you may reference reactive
values and functions.}
\item{height}{The height of the rendered plot, in pixels; or \code{'auto'} to
use the \code{offsetHeight} of the HTML element that is bound to this plot.
You can also pass in a function that returns the width in pixels or
\code{'auto'}; in the body of the function you may reference reactive
values and functions.}
\item{res}{Resolution of resulting plot, in pixels per inch. This value is
passed to \code{\link{png}}. Note that this affects the resolution of PNG

34
man/runGist.Rd Normal file
View File

@@ -0,0 +1,34 @@
% Generated by roxygen2 (4.0.1): do not edit by hand
\name{runGist}
\alias{runGist}
\title{Run a Shiny application from https://gist.github.com}
\usage{
runGist(gist, port = NULL,
launch.browser = getOption("shiny.launch.browser", interactive()))
}
\arguments{
\item{gist}{The identifier of the gist. For example, if the gist is
https://gist.github.com/jcheng5/3239667, then \code{3239667},
\code{'3239667'}, and \code{'https://gist.github.com/jcheng5/3239667'}
are all valid values.}
\item{port}{The TCP port that the application should listen on. Defaults to
choosing a random port.}
\item{launch.browser}{If true, the system's default web browser will be
launched automatically after the app is started. Defaults to true in
interactive sessions only.}
}
\description{
Download and launch a Shiny application that is hosted on GitHub as a gist.
}
\examples{
\dontrun{
runGist(3239667)
runGist("https://gist.github.com/jcheng5/3239667")
# Old URL format without username
runGist("https://gist.github.com/3239667")
}
}

40
man/runGitHub.Rd Normal file
View File

@@ -0,0 +1,40 @@
% Generated by roxygen2 (4.0.1): do not edit by hand
\name{runGitHub}
\alias{runGitHub}
\title{Run a Shiny application from a GitHub repository}
\usage{
runGitHub(repo, username = getOption("github.user"), ref = "master",
subdir = NULL, port = NULL,
launch.browser = getOption("shiny.launch.browser", interactive()))
}
\arguments{
\item{repo}{Name of the repository}
\item{username}{GitHub username}
\item{ref}{Desired git reference. Could be a commit, tag, or branch
name. Defaults to \code{"master"}.}
\item{subdir}{A subdirectory in the repository that contains the app. By
default, this function will run an app from the top level of the repo, but
you can use a path such as `\code{"inst/shinyapp"}.}
\item{port}{The TCP port that the application should listen on. Defaults to
choosing a random port.}
\item{launch.browser}{If true, the system's default web browser will be
launched automatically after the app is started. Defaults to true in
interactive sessions only.}
}
\description{
Download and launch a Shiny application that is hosted in a GitHub repository.
}
\examples{
\dontrun{
runGitHub("shiny_example", "rstudio")
# Can run an app from a subdirectory in the repo
runGitHub("shiny_example", "rstudio", subdir = "inst/shinyapp/")
}
}

View File

@@ -1,16 +1,10 @@
% Generated by roxygen2 (4.0.1): do not edit by hand
\name{runUrl}
\alias{runGist}
\alias{runGitHub}
\alias{runUrl}
\title{Run a Shiny application from a URL}
\usage{
runUrl(url, filetype = NULL, subdir = NULL, ...)
runGist(gist, ...)
runGitHub(repo, username = getOption("github.user"), ref = "master",
subdir = NULL, ...)
runUrl(url, filetype = NULL, subdir = NULL, port = NULL,
launch.browser = getOption("shiny.launch.browser", interactive()))
}
\arguments{
\item{url}{URL of the application.}
@@ -22,31 +16,19 @@ runGitHub(repo, username = getOption("github.user"), ref = "master",
default, this function will run an app from the top level of the repo, but
you can use a path such as `\code{"inst/shinyapp"}.}
\item{...}{Other arguments to be passed to \code{\link{runApp}()}, such as
\code{port} and \code{launch.browser}.}
\item{port}{The TCP port that the application should listen on. Defaults to
choosing a random port.}
\item{gist}{The identifier of the gist. For example, if the gist is
https://gist.github.com/jcheng5/3239667, then \code{3239667},
\code{'3239667'}, and \code{'https://gist.github.com/jcheng5/3239667'} are
all valid values.}
\item{repo}{Name of the repository.}
\item{username}{GitHub username. If \code{repo} is of the form
\code{"username/repo"}, \code{username} will be taken from \code{repo}.}
\item{ref}{Desired git reference. Could be a commit, tag, or branch name.
Defaults to \code{"master"}.}
\item{launch.browser}{If true, the system's default web browser will be
launched automatically after the app is started. Defaults to true in
interactive sessions only.}
}
\description{
\code{runUrl()} downloads and launches a Shiny application that is hosted at
a downloadable URL. The Shiny application must be saved in a .zip, .tar, or
.tar.gz file. The Shiny application files must be contained in the root
directory or a subdirectory in the archive. For example, the files might be
\code{myapp/server.r} and \code{myapp/ui.r}. The functions \code{runGitHub()}
and \code{runGist()} are based on \code{runUrl()}, using URL's from GitHub
(\url{https://github.com}) and GitHub gists (\url{https://gist.github.com}),
respectively.
Download and launch a Shiny application that is hosted at a downloadable
URL. The Shiny application must be saved in a .zip, .tar, or .tar.gz file.
The Shiny application files must be contained in a subdirectory in the
archive. For example, the files might be \code{myapp/server.r} and
\code{myapp/ui.r}.
}
\examples{
\dontrun{
@@ -56,19 +38,5 @@ runUrl('https://github.com/rstudio/shiny_example/archive/master.tar.gz')
runUrl("https://github.com/rstudio/shiny_example/archive/master.zip",
subdir = "inst/shinyapp/")
}
\dontrun{
runGist(3239667)
runGist("https://gist.github.com/jcheng5/3239667")
# Old URL format without username
runGist("https://gist.github.com/3239667")
}
\dontrun{
runGitHub("shiny_example", "rstudio")
# or runGitHub("rstudio/shiny_example")
# Can run an app from a subdirectory in the repo
runGitHub("shiny_example", "rstudio", subdir = "inst/shinyapp/")
}
}

View File

@@ -1,17 +0,0 @@
% Generated by roxygen2 (4.0.1): do not edit by hand
\name{serverInfo}
\alias{serverInfo}
\title{Collect information about the Shiny Server environment}
\usage{
serverInfo()
}
\value{
A list of the Shiny Server information.
}
\description{
This function returns the information about the current Shiny Server, such as
its version, and whether it is the open source edition or professional
edition. If the app is not served through the Shiny Server, this function
just returns \code{list(shinyServer = FALSE)}.
}

View File

@@ -4,7 +4,6 @@
\alias{as.shiny.appobj.character}
\alias{as.shiny.appobj.list}
\alias{as.shiny.appobj.shiny.appobj}
\alias{as.tags.shiny.appobj}
\alias{print.shiny.appobj}
\alias{shinyApp}
\alias{shinyAppDir}
@@ -23,8 +22,6 @@ as.shiny.appobj(x)
\method{as.shiny.appobj}{character}(x)
\method{print}{shiny.appobj}(x, ...)
\method{as.tags}{shiny.appobj}(x, ...)
}
\arguments{
\item{ui}{The UI definition of the app (for example, a call to

View File

@@ -15,7 +15,9 @@ be interpreted as CSS lengths (see \code{\link{validateCssUnit}}), numeric
values as pixels.}
\item{cellArgs}{Any additional attributes that should be used for each cell
of the layout.}
of the layout.
#'}
}
\description{
Lays out elements horizontally, dividing the available horizontal space into

View File

@@ -1,4 +1,4 @@
\name{tag}
\name{tagList}
\alias{tag}
\alias{tagAppendAttributes}
\alias{tagAppendChild}

View File

@@ -3,15 +3,12 @@
\alias{textOutput}
\title{Create a text output element}
\usage{
textOutput(outputId, container = if (inline) span else div, inline = FALSE)
textOutput(outputId, container = div)
}
\arguments{
\item{outputId}{output variable to read the value from}
\item{container}{a function to generate an HTML element to contain the text}
\item{inline}{use an inline (\code{span()}) or block container (\code{div()})
for the output}
}
\value{
A text output element that can be included in a panel
@@ -22,7 +19,7 @@ text will be included within an HTML \code{div} tag by default.
}
\details{
Text is HTML-escaped prior to rendering. This element is often used
to display \link{renderText} output variables.
to display \link{renderText} output variables.
}
\examples{
h3(textOutput("caption"))

View File

@@ -4,7 +4,7 @@
\title{Change the value of a checkbox group input on the client}
\usage{
updateCheckboxGroupInput(session, inputId, label = NULL, choices = NULL,
selected = NULL, inline = FALSE)
selected = NULL)
}
\arguments{
\item{session}{The \code{session} object passed to function given to
@@ -14,12 +14,10 @@ updateCheckboxGroupInput(session, inputId, label = NULL, choices = NULL,
\item{label}{The label to set for the input object.}
\item{choices}{List of values to show checkboxes for. If elements of the list
are named then that name rather than the value is displayed to the user.}
\item{choices}{A named vector or named list of options. For each item, the
name will be used as the label, and the value will be used as the value.}
\item{selected}{The values that should be initially selected, if any.}
\item{inline}{If \code{TRUE}, render the choices inline (i.e. horizontally)}
\item{selected}{A vector or list of options (values) which will be selected.}
}
\description{
Change the value of a checkbox group input on the client

View File

@@ -4,7 +4,7 @@
\title{Change the value of a radio input on the client}
\usage{
updateRadioButtons(session, inputId, label = NULL, choices = NULL,
selected = NULL, inline = FALSE)
selected = NULL)
}
\arguments{
\item{session}{The \code{session} object passed to function given to
@@ -14,13 +14,10 @@ updateRadioButtons(session, inputId, label = NULL, choices = NULL,
\item{label}{The label to set for the input object.}
\item{choices}{List of values to select from (if elements of the list are
named then that name rather than the value is displayed to the user)}
\item{choices}{A named vector or named list of options. For each item, the
name will be used as the label, and the value will be used as the value.}
\item{selected}{The initially selected value (if not specified then
defaults to the first value)}
\item{inline}{If \code{TRUE}, render the choices inline (i.e. horizontally)}
\item{selected}{A vector or list of options (values) which will be selected.}
}
\description{
Change the value of a radio input on the client

View File

@@ -18,22 +18,17 @@ updateSelectizeInput(session, inputId, label = NULL, choices = NULL,
\item{label}{The label to set for the input object.}
\item{choices}{A named vector or named list of options. For each item, the
name will be used as the label, and the value will be used as the value.}
\item{selected}{A vector or list of options (values) which will be selected.}
\item{options}{a list of options (see \code{\link{selectizeInput}})}
\item{server}{whether to store \code{choices} on the server side, and load
the select options dynamically on searching, instead of writing all
\code{choices} into the page at once (i.e., only use the client-side
version of \pkg{selectize.js})}
\item{choices}{List of values to select from. If elements of the list are
named then that name rather than the value is displayed to the user.}
\item{selected}{The initially selected value (or multiple values if
\code{multiple = TRUE}). If not specified then defaults to the first value
for single-select lists and no values for multiple select lists.}
\item{options}{A list of options. See the documentation of \pkg{selectize.js}
for possible options (character option values inside \code{\link{I}()} will
be treated as literal JavaScript code; see \code{\link{renderDataTable}()}
for details).}
}
\description{
Change the value of a select input on the client