shinyjs/ 0000755 0001762 0000144 00000000000 15132102300 011724 5 ustar ligges users shinyjs/tests/ 0000755 0001762 0000144 00000000000 15131777537 013123 5 ustar ligges users shinyjs/tests/testthat/ 0000755 0001762 0000144 00000000000 15132102300 014726 5 ustar ligges users shinyjs/tests/testthat/test-hidden.R 0000644 0001762 0000144 00000003315 15131777537 017320 0 ustar ligges users context("hidden") getClasses <- function(tag) { unlist(strsplit(htmltools::tagGetAttribute(tag, "class"), " ")) } clsName <- "shinyjs-hide" test_that("hidden fails on plain text", { expect_error(hidden("abc"), "Invalid shiny tag") }) test_that("hidden works on simple div", { tag <- hidden(shiny::div("abc")) expect_true(clsName %in% getClasses(tag)) }) test_that("hidden works on complex div", { tag <- hidden(shiny::div(shiny::span("abc"))) expect_true(clsName %in% getClasses(tag)) }) test_that("hidden works when div already contains a class", { tag <- hidden(shiny::div("abc", class = "test")) expect_true(clsName %in% getClasses(tag)) }) test_that("hidden errors when one of multiple tags is not a tag", { expect_error(hidden(shiny::p("abc"), "abc"), "Invalid shiny tag") expect_error(hidden(list(shiny::p("abc"), "abc")), "Invalid shiny tag") expect_error(hidden(shiny::tagList(shiny::p("abc"), "abc")), "Invalid shiny tag") }) test_that("hidden works when given multiple tags", { res <- hidden(shiny::p("abc"), shiny::span("abc")) expect_equal(length(res), 2) expect_true(clsName %in% getClasses(res[[1]])) expect_true(clsName %in% getClasses(res[[2]])) }) test_that("hidden works when given list", { res <- hidden(list(shiny::p("abc"), shiny::span("abc"))) expect_equal(length(res), 2) expect_true(clsName %in% getClasses(res[[1]])) expect_true(clsName %in% getClasses(res[[2]])) }) test_that("hidden works when given tagList", { res <- hidden(shiny::tagList(shiny::p("abc"), shiny::span("abc"))) expect_equal(length(res), 2) expect_true(clsName %in% getClasses(res[[1]])) expect_true(clsName %in% getClasses(res[[2]])) }) shinyjs/tests/testthat.R 0000644 0001762 0000144 00000000076 15104020675 015071 0 ustar ligges users library(testthat) library(shinyjs) test_check("shinyjs") shinyjs/MD5 0000644 0001762 0000144 00000012064 15132102300 012237 0 ustar ligges users f0eef3e7cc6a96c64ade0585eb025aea *DESCRIPTION 9ddd06bb65ce3e8cdcc8792902b9102a *LICENSE 38eff2f64ef2e7204137100971f0a99c *NAMESPACE 66274f2e0c82d6687efaf8a079bb43d3 *NEWS.md b2929f21ab990807a87bc22ad2603fd5 *R/defunct-colourInput.R 3e9fe077c70bb4bef1a284e5a5ef9d20 *R/delay.R bc9c3989464fc46abc07e8eccd547490 *R/disabled.R 1f02ce93496a5f16e808a56624893e06 *R/extendShinyjs.R 73515e1f82cd19a9dd2b5d560d5bcd4d *R/globals.R ffb828168aec537522c4338eeb5ad4d2 *R/hidden.R c1c764b0d5d7d6526cb07cb6e8289212 *R/inlineCSS.R c7dd20b89d928180ef7583d09879fa07 *R/jsFunc-aaa.R da77c373f33cd1221e1fbba3c62450c7 *R/jsFunc-classFuncs.R 8ae5efb3ec062659f25682a76dab650a *R/jsFunc-click.R 1dbc84be207b621527a7d8aa3342691c *R/jsFunc-html.R 17ae46648464dacea6dd6554deee5d75 *R/jsFunc-messageFuncs.R a2a6402ed643f8b0c076b1e862ba6b00 *R/jsFunc-runjs.R 8c412727584c697e3cef413abfa8ea53 *R/jsFunc-stateFuncs.R 43eb436250243475850d41c2829031ab *R/jsFunc-visibilityFuncs.R b2a053fbf1fcd7fe89fa11449bc5bf49 *R/onevent.R cb71d8663ca6f2b69ef2e9d88dbe1f35 *R/refresh.R a30929a03906f166f0ad8953a286bd41 *R/reset.R c134871c503bcba1daf9d3ec0ab41cdb *R/runExample.R 030da409935f86664f65f4d2c0025535 *R/runcode.R 680f62f791d2c9b4c1f22bd70b8ddcd1 *R/shinyjs-package.R 31bca7b7fd408d9a2658fcba9de3d31b *R/showLog.R bd331b1e0fc72f852842854d88669621 *R/useShinyjs.R 007fb0b91d2a45d7e534f913ef422cf2 *R/utils.R 36cf8ff029a53b287b9a7052e1a133f2 *R/zzz.R ca0b75264adf28868bb99df9708d1b3c *README.md 72a49850267b6fa04347bfdc7e607dc2 *build/vignette.rds b7d369e31ea1b815c1b461b01f2ea6a0 *inst/doc/shinyjs-example.R 34f97b9a219fad64de5df58718665bd5 *inst/doc/shinyjs-example.Rmd 7770f0401add979ab8036e1311fd6659 *inst/doc/shinyjs-example.html b7d369e31ea1b815c1b461b01f2ea6a0 *inst/doc/shinyjs-extend.R 15b53bdaa90a7c73dbb3b06ad40dbc7b *inst/doc/shinyjs-extend.Rmd fea2acbd13b4241d570b821b0f3564e1 *inst/doc/shinyjs-extend.html b7d369e31ea1b815c1b461b01f2ea6a0 *inst/doc/shinyjs-usage.R 84173a18382feb2eddf6b59de6fb1c6b *inst/doc/shinyjs-usage.Rmd dff1433de78428ddbaeb8cf9b4b107dc *inst/doc/shinyjs-usage.html 91158a198ad94f5220d0eef57272b08b *inst/examples/basic/DESCRIPTION e4ca97bfd3a0c0186f54ac0dfa4b5445 *inst/examples/basic/app.R 9f6c6c5829dae52754a3ad5af3dec628 *inst/examples/basic/helper-text.R 3c18b8235426323dbeb350fe07a0c0c9 *inst/examples/demo/helpers.R 6fe980bba47f26baecec7184ad888407 *inst/examples/demo/server.R db3429e7fa9bdc45c77e5a767e8431c8 *inst/examples/demo/ui.R 22d9e69c0ebaff22a24e241a0244532e *inst/examples/demo/www/github-green-right.png 507fa324f50735ea46bb37f49b1d9a87 *inst/examples/demo/www/header.png 3da20a2fd13a853a74d3fee518324842 *inst/examples/demo/www/style.css daf8f84ad8078ec6e293939a4f2a7c95 *inst/examples/sandbox/helpers.R 8e4b5c3cdf52f4b209c83ded6853bbe3 *inst/examples/sandbox/server.R 5c1699fa200870ed013a60b3d50e0d7e *inst/examples/sandbox/ui.R 22d9e69c0ebaff22a24e241a0244532e *inst/examples/sandbox/www/github-green-right.png 507fa324f50735ea46bb37f49b1d9a87 *inst/examples/sandbox/www/header.png 5ec22f7c72d434a7cee8259fd7436853 *inst/examples/sandbox/www/style.css 59ad37b4c3608ec64757604a3f725b61 *inst/img/banner.png 4dc73a7d70dc509043c7278330c51254 *inst/img/colourPickerGadget.gif 4f28646b91bc197c9877558927d6a08a *inst/img/colourpickerscrnshot.png b9fe8d5c3f813c3e24292fef51d3210e *inst/img/demo-basic-v1.png b1543466ee93e7fa7767d73280539a91 *inst/img/extendshinyjs-demo.gif 2b3c30bb4f22529fe913f14b5e5f9f76 *inst/img/extendshinyjs-params.gif 61fa611eb5d2e1f9660e6525da66465e *inst/img/hex.png b460b8f02bf4b319494e55d36c667613 *inst/img/shinyjs-logo-whitebg-small.png 7aeb90e1a4844ea9391ec785114be3b1 *inst/srcjs/inject.js 71de53e20fc6471c18417894630c0cae *inst/srcjs/shinyjs-default-funcs.js fdfb11f09e9fe2d312d369a91bc8266e *man/classFuncs.Rd 09c608bf2b1284b1efb6e419ef9dbc85 *man/click.Rd 18eb2ee1c5d978790a5ae56c8d946283 *man/delay.Rd eb9efa4cc8a2d19d26a0c7f258004091 *man/disabled.Rd 4d7354f21c623cacec81f1d003fb2ff4 *man/extendShinyjs.Rd 90929e13952841583f57babf8edc65c6 *man/hidden.Rd e1668d7d6128d57ee220456fb3f1f34e *man/html.Rd 14971d93bd93eae9f020fb4117648666 *man/inlineCSS.Rd ae749931a0e5f5f8f1f1f492fb70f930 *man/js.Rd 21567757f7d8421b26ef649f4e2e9bd1 *man/messageFuncs.Rd 8f6c21cea9ab455594500276b9306438 *man/onevent.Rd cfe114cb36d718d1b1384a0934520af5 *man/refresh.Rd 1cc7ef121865758deb2f366a7d7bcba1 *man/removeEvent.Rd c0510c29390a7dffbbca755be9200f79 *man/reset.Rd 635c51b8c2896325fd3d1ee0ea8b86ab *man/runExample.Rd 45374ddf0490f69595098ad6a31ddeb1 *man/runcode.Rd 7b66c72adea636622ce198b7cfa4217f *man/runjs.Rd 01df6d102c0249b8f6a471a3ba1d16ec *man/shinyjs-defunct.Rd 7f277705116e359902c4a2feff6268bd *man/shinyjs-package.Rd f59a32d1502c4bb5f135dadf5eae6ca7 *man/showLog.Rd af3abeb5ae8d19aec55722062f54cc40 *man/stateFuncs.Rd 88aef5aba9e90adf2b88fcdb8e59a1a3 *man/useShinyjs.Rd b748fa7981d14840d018247ee61ba3e2 *man/visibilityFuncs.Rd 96c858d7d7fbfb4f62d3bfb74a36251a *tests/testthat.R a61938c993a90c12340c84978f93a526 *tests/testthat/test-hidden.R 34f97b9a219fad64de5df58718665bd5 *vignettes/shinyjs-example.Rmd 15b53bdaa90a7c73dbb3b06ad40dbc7b *vignettes/shinyjs-extend.Rmd 84173a18382feb2eddf6b59de6fb1c6b *vignettes/shinyjs-usage.Rmd shinyjs/R/ 0000755 0001762 0000144 00000000000 15132004023 012130 5 ustar ligges users shinyjs/R/onevent.R 0000644 0001762 0000144 00000021250 15104020675 013743 0 ustar ligges users #' Run R code when an event is triggered on an element #' #' \code{onclick} runs an R expression (either a \code{shinyjs} function or any other code) #' when an element is clicked.\cr\cr #' \code{onevent} is similar, but can be used when any event is triggered on the element, #' not only a mouse click. See below for a list of possible event types. Using "click" #' results in the same behaviour as calling \code{onclick}.\cr\cr #' This action can be reverted by calling \code{\link[shinyjs]{removeEvent}}. #' #' @param event The event that needs to be triggered to run the code. See below #' for a list of event types. #' @param id The id of the element/Shiny tag #' @param expr The R expression or function to run after the event is triggered. #' If a function with an argument is provided, it will be called with the #' JavaScript Event properties as its argument. Using a function can be useful #' when you want to know, for example, what key was pressed on a "keypress" event #' or the mouse coordinates in a mouse event. See below for a list of properties. #' @param add If \code{TRUE}, then add \code{expr} to be executed after any #' other code that was previously set using \code{onevent} or \code{onclick}; otherwise #' \code{expr} will overwrite any previous expressions. Note that this parameter #' works well in web browsers but is buggy when using the RStudio Viewer. #' @param properties A list of JavaScript Event properties that should be available #' to the argument of the \code{expr} function. See below for more information about #' Event properties. #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @return An ID that can be used by \code{\link[shinyjs]{removeEvent}} to remove #' the event listener. See \code{\link[shinyjs]{removeEvent}} for more details. #' @seealso \code{\link[shinyjs]{removeEvent}}, #' \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @section Event types: #' Any standard \href{https://api.jquery.com/category/events/mouse-events/}{mouse} or #' \href{https://api.jquery.com/category/events/keyboard-events/}{keyboard} events #' that are supported by JQuery can be used. The standard list of events that can be used is: #' \code{click}, \code{dblclick}, \code{hover}, \code{mousedown}, \code{mouseenter}, #' \code{mouseleave}, \code{mousemove}, \code{mouseout}, \code{mouseover}, \code{mouseup}, #' \code{keydown}, \code{keypress}, \code{keyup}. You can also use any other non #' standard events that your browser supports or with the use of plugins (for #' example, there is a \href{https://github.com/jquery/jquery-mousewheel}{mousewheel} #' plugin that you can use to listen to mousewheel events). #' @section Event properties: #' If a function is provided to \code{expr}, the function will receive a list #' of JavaScript Event properties describing the current event as an argument. #' Different properties are available for different event types. The full list #' of properties that can be returned is: \code{altKey}, \code{button}, #' \code{buttons}, \code{clientX}, \code{clientY}, \code{ctrlKey}, \code{pageX}, #' \code{pageY}, \code{screenX}, \code{screenY}, \code{shiftKey}, \code{which}, #' \code{charCode}, \code{key}, \code{keyCode}, \code{offsetX}, \code{offsetY}. #' If you want to retrieve any additional properties that are available in #' JavaScript for your event type, you can use the \code{properties} parameter. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' p(id = "date", "Click me to see the date"), #' p(id = "coords", "Click me to see the mouse coordinates"), #' p(id = "disappear", "Move your mouse here to make the text below disappear"), #' p(id = "text", "Hello") #' ), #' server = function(input, output) { #' onclick("date", alert(date())) #' onclick("coords", function(event) { alert(event) }) #' onevent("mouseenter", "disappear", hide("text")) #' onevent("mouseleave", "disappear", show("text")) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' onclick("disappear", toggle("text")) #' onclick(expr = text("date", date()), id = "date") #' } #' @name onevent #' @rdname onevent #' @export onclick <- function(id, expr, add = FALSE, asis = FALSE) { oneventHelper("click", id, substitute(expr), add = add, properties = NULL, asis = asis) } #' @rdname onevent #' @export onevent <- function(event, id, expr, add = FALSE, properties = NULL, asis = FALSE) { oneventHelper(event, id, substitute(expr), add, properties, asis = asis) } oneventHelper <- function(event, id, expr, add, properties, asis) { # evaluate expressions in the caller's environment parentFrame <- parent.frame(2) # get the Shiny session session <- getSession() # Make sure onevent works with namespaces (shiny modules) if (inherits(session, "session_proxy")) { if (!asis) { id <- session$ns(id) } } # attach the event callback from JS to call this function to execute the # given expression. To support multiple event handlers, each time this # is called, a random number is attached to the Shiny input id shinyInputId <- sprintf("shinyjs-%s-%s-input-%s", id, as.integer(sample(1e9, 1)), event) shinyInputIdJs <- shinyInputId if (inherits(session, "session_proxy")) { shinyInputIdJs <- session$ns(shinyInputIdJs) } session$sendCustomMessage( "shinyjs-onevent", list( event = event, id = id, shinyInputId = shinyInputIdJs, add = add, customProps = properties ) ) # save the unevaluated expression so that it won't have a static value # every time the given event occurs expr <- deparse(expr) shiny::observeEvent(session$input[[shinyInputId]], { ret <- eval(parse(text = expr), envir = parentFrame) # If a callback function was provided, call it with the event as argument if (is.function(ret)) { if (length(formals(ret)) == 0) { ret() } else { event <- session$input[[shinyInputId]] event[['shinyjsRandom']] <- NULL ret(event) } } # If an expression was provided, evaluate it else { ret } }) invisible(shinyInputIdJs) } #' Remove an event that was added to an element #' #' This function can be used to revert the action of #' \code{\link[shinyjs]{onclick}} or \code{\link[shinyjs]{onevent}}. #' @param event Either an event type (see below for a list of event types) or #' an event ID (the return value from #' \code{\link[shinyjs]{onclick}} or \code{\link[shinyjs]{onevent}}). #' If an event type is provided (eg. "hover"), then all events of this type #' attached to the given element will be removed. If an event ID is provided, #' then only that specific event will be removed. #' See examples for clarification. #' @param id The ID of the element/Shiny tag. Must match the ID used in #' \code{\link[shinyjs]{onclick}} or \code{\link[shinyjs]{onevent}}. #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @inheritSection onevent Event types #' @seealso \code{\link[shinyjs]{onclick}}, #' \code{\link[shinyjs]{onevent}} #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' p(id = "myel", "Hover over me to see the date, the time, and a random integer"), #' actionButton("remove_date", "Remove date hover event"), #' actionButton("remove_all", "Remove all hover events") #' ), #' server = function(input, output) { #' onevent("hover", "myel", print(format(Sys.time(), "%H:%M:%S"))) #' onevent("hover", "myel", print(sample(100, 1)), add = TRUE) #' date_event_id <- onevent("hover", "myel", print(as.character(Sys.Date())), add = TRUE) #' #' observeEvent(input$remove_all, { #' removeEvent("hover", "myel") #' }) #' observeEvent(input$remove_date, { #' removeEvent(date_event_id, "myel") #' }) #' } #' ) #' } #' @export removeEvent <- function(event, id, asis = FALSE) { fxn <- "removeEvent" params <- list(event = event, id = id, asis = asis) jsFuncHelper(fxn, params) } shinyjs/R/jsFunc-runjs.R 0000644 0001762 0000144 00000001437 15104020675 014661 0 ustar ligges users #' Run JavaScript code #' #' Run arbitrary JavaScript code. #' #' @param code JavaScript code to run. #' @seealso \code{\link[shinyjs]{useShinyjs}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Run JS code that simply shows a message #' runjs("var today = new Date(); alert(today);") #' }) #' } #' ) #' } #' @export runjs <- function(code) { fxn <- "runjs" params <- list(code = code) jsFuncHelper(fxn, params) } shinyjs/R/delay.R 0000644 0001762 0000144 00000004244 15131777537 013407 0 ustar ligges users #' Execute R code after a specified number of milliseconds has elapsed #' #' You can use \code{delay} if you want to wait a specific amount of time before #' running code. This function can be used in combination with other \code{shinyjs} #' functions, such as hiding or resetting an element in a few seconds, but it #' can also be used with any code as long as it's used inside a Shiny app. #' #' @param ms The number of milliseconds to wait (1000 milliseconds = 1 second) #' before running the expression. #' @param expr The R expression to run after the specified number of milliseconds #' has elapsed. #' #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' p(id = "text", "This text will disappear after 3 seconds"), #' actionButton("close", "Close the app in half a second") #' ), #' server = function(input, output) { #' delay(3000, hide("text")) #' observeEvent(input$close, { #' delay(500, stopApp()) #' }) #' } #' ) #' } #' @export delay <- function(ms, expr) { ms <- round(ms) # get the Shiny session session <- getSession() hashable <- sprintf("%s_%s_%s_%s", ms, as.integer(Sys.time()), as.integer(sample(1e9, 1)), deparse(substitute(expr))) hash <- digest::digest(hashable, algo = "md5") # send a call to JavaScript to let us know when the delay is up shinyInputId <- paste0("shinyjs-delay-", hash) shinyInputIdJs <- shinyInputId if (inherits(session, "session_proxy")) { shinyInputIdJs <- session$ns(shinyInputIdJs) } session$sendCustomMessage("shinyjs-delay", list(ms = ms, shinyInputId = shinyInputIdJs)) # listen for a response from javascript when the delay is up shiny::observeEvent(session$input[[shinyInputId]], once = TRUE, { expr }) invisible(NULL) } shinyjs/R/refresh.R 0000644 0001762 0000144 00000000777 15104020675 013736 0 ustar ligges users #' Refresh the page #' #' @examples #' if (interactive()) { #' library(shiny) #' ui <- fluidPage( #' useShinyjs(), #' textInput("text", "Text", "text"), #' actionButton("refresh", "Refresh") #' ) #' #' server <- function(input, output, session) { #' observeEvent(input$refresh, { #' refresh() #' }) #' } #' #' shinyApp(ui, server) #' } #' #' @export refresh <- function() { fxn <- "refresh" params <- list() jsFuncHelper(fxn, params) } shinyjs/R/hidden.R 0000644 0001762 0000144 00000003146 15131777537 013544 0 ustar ligges users #' Initialize a Shiny tag as hidden #' #' Create a Shiny tag that is invisible when the Shiny app starts. The tag can #' be made visible later with [toggle()] or [show()]. #' #' @param ... Shiny tag (or tagList or list of of tags) to make invisible #' @seealso [useShinyjs()], [toggle()], [show()], [hide()] #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @return The tag (or tags) that was given as an argument in a hidden state. #' @examples #' if (interactive()) { #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' hidden( #' p(id = "element", "I was born invisible") #' ) #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' show("element") #' }) #' } #' ) #' } #' #' library(shiny) #' hidden(span(id = "a"), div(id = "b")) #' hidden(tagList(span(id = "a"), div(id = "b"))) #' hidden(list(span(id = "a"), div(id = "b"))) #' @export hidden <- function(...) { tags <- list(...) # recursively add the hidden class to all tags if (length(tags) == 1 && inherits(tags[[1]], "shiny.tag")) { tags[[1]] <- shiny::tagAppendAttributes( tags[[1]], class = "shinyjs-hide" ) return( tags[[1]] ) } else if (length(tags) == 1 && is.list(tags[[1]])) { return( lapply(tags[[1]], hidden) ) } else if (length(tags) > 1) { return( lapply(tags, hidden) ) } else { errMsg("Invalid shiny tags given to `hidden`") } } shinyjs/R/defunct-colourInput.R 0000644 0001762 0000144 00000001317 15131777537 016260 0 ustar ligges users #' @rdname shinyjs-defunct #' @export #' @keywords internal colourInput <- function(...) { .Defunct("colourInput", package = "colourpicker", msg = "colourInput() has been moved to the 'colourpicker' package.") } #' @rdname shinyjs-defunct #' @export #' @keywords internal updateColourInput <- function(...) { .Defunct("updateColourInput", package = "colourpicker", msg = "updateColourInput() has been moved to the 'colourpicker' package.") } #' @rdname shinyjs-defunct #' @export #' @keywords internal colourPicker <- function(...) { .Defunct("colourPicker", package = "colourpicker", msg = "colourPicker() has been moved to the 'colourpicker' package.") } shinyjs/R/jsFunc-html.R 0000644 0001762 0000144 00000004055 15104020675 014463 0 ustar ligges users #' Change the HTML (or text) inside an element #' #' Change the text or HTML inside an element. The given HTML can be any #' R expression, and it can either be appended to the currentcontents of the element #' or overwrite it (default). #' #' @param id The id of the element/Shiny tag #' @param html The HTML/text to place inside the element. Can be either simple #' plain text or valid HTML code. #' @param add If \code{TRUE}, then append \code{html} to the contents of the element; #' otherwise overwrite it. #' @param selector JQuery selector of the elements to target. Ignored if the \code{id} #' argument is given. #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' p(id = "element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Change the following line for more examples #' html("element", paste0("The date is ", date())) #' }) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' html("element", "Hello!") #' html("element", " Hello!", TRUE) #' html("element", "bold that was achieved with HTML") #' local({val <- "some text"; html("element", val)}) #' html(id = "element", add = TRUE, html = input$btn) #' } #' @export html <- function(id = NULL, html = NULL, add = FALSE, selector = NULL, asis = FALSE) { fxn <- "html" params <- list(id = id, html = html, add = add, selector = selector, asis = asis) jsFuncHelper(fxn, params) } shinyjs/R/showLog.R 0000644 0001762 0000144 00000003663 15104020675 013717 0 ustar ligges users #' Print any JavaScript console.log messages in the R console #' #' When developing and debugging a Shiny that uses custom JavaScript code, #' it can be helpful to use \code{console.log()} messages in JavaScript. This #' function allows you to see these messages printed in the R console directly #' rather than having to open the JavaScript console in the browser to view the #' messages.\cr\cr #' This function must be called in a Shiny app's server. #' @note Log messages that cannot be serialized in JavaScript (such as many #' JavaScript Event objects that are cyclic) will not be printed in R. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' textInput("text", "Type something") #' ), #' server = function(input, output) { #' showLog() #' logjs("App started") #' observe({ #' logjs(paste("Length of text:", nchar(input$text))) #' }) #' } #' ) #' } #' @seealso [logjs()] #' @export showLog <- function() { session <- getSession() if (!is.null(attr(session, "shinyjs_showLog"))) { return() } attr(session, "shinyjs_showLog") <- TRUE # Capture the console.log function and overwrite it to send the message to R shiny::insertUI("head", "beforeEnd", { shiny::singleton(shiny::tags$head(shiny::tags$script( '(function(){ var oldLog = console.log; var queue = new ShinySenderQueue(); console.log = function (message) { try { queue.send("shinyjs-showLog", message); } catch(err) {} oldLog.apply(console, arguments); }; })();' ))) }, immediate = TRUE) shiny::observeEvent(session$input[['shinyjs-showLog']], { message("[JAVASCRIPT LOG] ", jsonlite::toJSON(session$input[['shinyjs-showLog']], auto_unbox = TRUE) ) }) } shinyjs/R/zzz.R 0000644 0001762 0000144 00000002642 15131777537 013146 0 ustar ligges users # Show a random startup tip # Copied from ggplot2 .onAttach <- function(...) { if (!interactive()) return() tips <- c( "Need shinyjs help? You can ask any Shiny-related question in the RStudio Community forums:\n\thttps://community.rstudio.com/c/shiny", "Don't forget that shinyjs can also be used in Rmd documents!", "Watch shinyjs tutorial videos and read the full documentation:\n\thttps://deanattali.com/shinyjs/", "Find out what's new in shinyjs:\n\thttps://github.com/daattali/shinyjs/releases", "Answers to common shinyjs questions can be found in the FAQ:\n\thttps://deanattali.com/shinyjs/help", "Need Shiny help? I'm available for consulting:\n\thttps://attalitech.com", "Use suppressPackageStartupMessages() to eliminate package startup messages.", "Stackoverflow is a great place to get help:\n\thttps://stackoverflow.com/tags/shinyjs", "Find out advanced usage of shinyjs:\n\thttps://deanattali.com/shinyjs/advanced", "Love shinyjs? Consider donating:\n\thttps://github.com/sponsors/daattali", "See a demo of shinyjs and learn more:\n\thttps://deanattali.com/shinyjs/demo", "You can use shinyjs to call your own JavaScript functions:\n\thttps://deanattali.com/shinyjs/extend", "Learn different usages for shinyjs and other Shiny tricks:\n\thttps://deanattali.com/blog/advanced-shiny-tips" ) tip <- sample(tips, 1) packageStartupMessage(tip) } shinyjs/R/inlineCSS.R 0000644 0001762 0000144 00000005057 15131777537 014143 0 ustar ligges users #' Add inline CSS #' #' Add inline CSS to a Shiny app. This is simply a convenience function that #' gets called from a Shiny app's UI to make it less tedious to add inline CSS. #' If there are many CSS rules, it is recommended to use an external stylesheet.\cr\cr #' CSS is a simple way to describe how elements on a web page should be #' displayed (position, colour, size, etc.). You can learn the basics #' at \href{https://www.w3schools.com/css/}{W3Schools}. #' #' @param rules The CSS rules to add. Can either be a string with valid #' CSS code, or a named list of the form #' \code{list(selector = declarations)}, where \code{selector} is a valid #' CSS selector and \code{declarations} is a string or vector of declarations. #' See examples for clarification. #' @return Inline CSS code that is automatically inserted to the app's #' \code{
} tag. #' @examples #' if (interactive()) { #' library(shiny) #' #' # Method 1 - passing a string of valid CSS #' shinyApp( #' ui = fluidPage( #' inlineCSS("#big { font-size:30px; } #' .red { color: red; border: 1px solid black;}"), #' p(id = "big", "This will be big"), #' p(class = "red", "This will be red and bordered") #' ), #' server = function(input, output) {} #' ) #' #' # Method 2 - passing a list of CSS selectors/declarations #' # where each declaration is a full declaration block #' shinyApp( #' ui = fluidPage( #' inlineCSS(list( #' "#big" = "font-size:30px", #' ".red" = "color: red; border: 1px solid black;" #' )), #' p(id = "big", "This will be big"), #' p(class = "red", "This will be red and bordered") #' ), #' server = function(input, output) {} #' ) #' #' # Method 3 - passing a list of CSS selectors/declarations #' # where each declaration is a vector of declarations #' shinyApp( #' ui = fluidPage( #' inlineCSS(list( #' "#big" = "font-size:30px", #' ".red" = c("color: red", "border: 1px solid black") #' )), #' p(id = "big", "This will be big"), #' p(class = "red", "This will be red and bordered") #' ), #' server = function(input, output) {} #' ) #' } #' @export inlineCSS <- function(rules) { if (is.list(rules)) { rules <- paste( lapply(names(rules), function(x) { paste0(x, "{", paste(rules[[x]], collapse = ";") , "}") }), collapse = "") } insertHead(shiny::tags$style(shiny::HTML(rules))) } shinyjs/R/jsFunc-aaa.R 0000644 0001762 0000144 00000003264 15104020675 014242 0 ustar ligges users # main powerhorse that takes an R command and translates it to shinyjs JS function jsFunc <- function(...) { params <- eval(substitute(alist(...))) if (!is.null(names(params)) && any(vapply(names(params), nzchar, 1L) == 0)) { errMsg(paste0("you cannot mix named and unnamed arguments in the same function call", " (function: ", as.character(match.call()[1]), ")")) } # evaluate the parameters in the appropriate environment parentFrame <- parent.frame(1) params <- lapply(params, function(x){ eval(x, envir = parentFrame) }) # figure out what JS function to call, make sure to work with namespacing as well pkgName <- "shinyjs" extensionName <- "js" regex <- sprintf("^(%s:{2,3})?(%s\\$)?((\\w)+)$", pkgName, extensionName) fxn <- as.character(as.list(match.call()[1])) fxn <- sub(regex, "\\3", fxn) jsFuncHelper(fxn, params) } # similar to jsFunc, but here we already know the function name and parameters jsFuncHelper <- function(fxn, params) { # is fxn a function defined by shinyjs (not by the user with extendShinyjs) isShinyjsFunction <- fxn %in% shinyjsFunctionNames("all") # get the Shiny session session <- getSession() fxn <- paste0("shinyjs-", fxn) # respect Shiny modules/namespaces in shinyjs functions if (inherits(session , "session_proxy") && isShinyjsFunction) { if ("id" %in% names(params) && !is.null(params[['id']])) { if (!"asis" %in% names(params) || !params[['asis']]) { params[['id']] <- session$ns(params[['id']]) } } } # call the javascript function session$sendCustomMessage( type = fxn, message = params) invisible(NULL) } shinyjs/R/utils.R 0000644 0001762 0000144 00000006106 15131777537 013450 0 ustar ligges users # common way to print error messages errMsg <- function(x) { stop(sprintf("shinyjs: %s", x), call. = FALSE) } # get the shiny session object getSession <- function() { session <- shiny::getDefaultReactiveDomain() if (is.null(session)) { errMsg(paste( "could not find the Shiny session object. This usually happens when a", "shinyjs function is called from a context that wasn't set up by a Shiny session." )) } session } # set up some javascript functions to work with shinyjs and any other resources setupJS <- function(jsFuncs, script, text, ...) { # add a shiny message handler binding for each supported method tpl <- paste0( "Shiny.addCustomMessageHandler('shinyjs-%s', function(params) {", " shinyjs.debugMessage('shinyjs: calling function \"%s\" with parameters:');", " shinyjs.debugMessage(params);", " shinyjs.%s(params);", "});") controllers <- lapply(jsFuncs, function(x) { sprintf(tpl, x, x, x)}) controllers <- paste(controllers, collapse = "\n") # ensure the same scripts don't get added to the HTML twice shinyjsContent <- shiny::singleton( insertHead( # add the message handlers shiny::tags$script(shiny::HTML(controllers)), # add the actual javascript code shinyjsInlcudeScript(script), shinyjsInlineScript(text), # add any extra tags ... ) ) # inject the content via JavaScript if necessary if (!is.null(.globals$inject) && .globals$inject) { shinyjsContent <- as.character(shinyjsContent) session <- getSession() session$sendCustomMessage('shinyjs-inject', shinyjsContent) } else { shinyjsContent } } # insert content into the tag of the document if this is a proper HTML # Shiny app, but if it's inside an interactive Rmarkdown document then don't # use as it won't work insertHead <- function(...) { if (is.null(.globals$astext) || .globals$astext) { shiny::tagList(...) } else { shiny::tags$head(...) } } # include a JavaScript script shinyjsInlcudeScript <- function(script) { if (missing(script) || is.null(script)) { return(NULL) } else { shiny::tags$script(src = script) } } # include a JavaScript string shinyjsInlineScript <- function(text) { if (missing(text) || is.null(text)) { return(NULL) } else { shiny::tags$script(shiny::HTML(text)) } } # names of JS functions defined by shinyjs shinyjsFunctionNames <- function(type = c("all", "core")) { type <- match.arg(type) # core functions are defined in JS and exported in R jsFuncs <- c( "show", "hide", "toggle", "enable", "disable", "toggleState", "addClass", "removeClass", "toggleClass", "html", "onevent", "removeEvent", "alert", "logjs", "runjs", "reset", "delay", "click", "refresh" ) if (type == "all") { jsFuncs <- c( jsFuncs, # additional functions which are only defined on the JS side "debug", "debugMessage", "getParams", "initShinyjs" ) } jsFuncs } shinyjs/R/disabled.R 0000644 0001762 0000144 00000003357 15131777537 014064 0 ustar ligges users #' Initialize a Shiny input as disabled #' #' Create a Shiny input that is disabled when the Shiny app starts. The input can #' be enabled later with [toggleState()] or [enable()]. #' #' @param ... Shiny input (or tagList or list of of tags that include inputs) to #' disable. #' @seealso [useShinyjs()], [toggleState()], [enable()], [disable()] #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @return The tag (or tags) that was given as an argument in a disabled state. #' @examples #' if (interactive()) { #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' disabled( #' textInput("element", NULL, "I was born disabled") #' ) #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' enable("element") #' }) #' } #' ) #' } #' #' library(shiny) #' disabled(numericInput("num", NULL, 5), dateInput("date", NULL)) #' @export disabled <- function(...) { tags <- list(...) # recursively add the disabled class to all tags if (length(tags) == 1 && inherits(tags[[1]], "shiny.tag")) { # don't do anything if an input has a head tag associated to it if (tags[[1]][['name']] == "head") { return(tags[[1]]) } tags[[1]] <- shiny::tagAppendAttributes( tags[[1]], class = "shinyjs-disabled" ) return( tags[[1]] ) } else if (length(tags) == 1 && is.list(tags[[1]])) { return( lapply(tags[[1]], disabled) ) } else if (length(tags) > 1) { return( lapply(tags, disabled) ) } else { errMsg("Invalid shiny tags given to `disabled`") } } shinyjs/R/runExample.R 0000644 0001762 0000144 00000002427 15131777537 014432 0 ustar ligges users #' Run shinyjs examples #' #' Launch a \code{shinyjs} example Shiny app that shows how to #' easily use \code{shinyjs} in an app.\cr\cr #' Run without any arguments to see a list of available example apps. #' The "demo" example is also #' \href{https://daattali.com/shiny/shinyjs-demo/}{available online} #' to experiment with. #' #' @param example The app to launch #' @examples #' ## Only run this example in interactive R sessions #' if (interactive()) { #' # List all available example apps #' runExample() #' #' runExample("sandbox") #' runExample("demo") #' } #' @export runExample <- function(example) { validExamples <- paste0( 'Valid examples are: "', paste(list.files(system.file("examples", package = "shinyjs")), collapse = '", "'), '"') if (missing(example) || !nzchar(example)) { message( 'Please run `runExample()` with a valid example app as an argument.\n', validExamples) return(invisible(NULL)) } appDir <- system.file("examples", example, package = "shinyjs") if (appDir == "") { errMsg(sprintf("could not find example app `%s`\n%s", example, validExamples)) } shiny::runApp(appDir, display.mode = "normal") } shinyjs/R/jsFunc-classFuncs.R 0000644 0001762 0000144 00000011120 15104020675 015612 0 ustar ligges users #' Add/remove CSS class #' #' Add or remove a CSS class from an HTML element.\cr\cr #' \strong{\code{addClass}} adds a CSS class, \strong{\code{removeClass}} #' removes a CSS class, \strong{\code{toggleClass}} adds the class if it is #' not set and removes the class if it is already set.\cr\cr #' \strong{\code{addCssClass}}, \strong{\code{removeCssClass}}, and #' \strong{\code{toggleCssClass}} are synonyms that may be safer to use if you're #' working with S4 classes (since they don't mask any existing S4 functions).\cr\cr #' If \code{condition} is given to \code{toggleClass}, that condition will be used #' to determine if to add or remove the class. The class will be added if the #' condition evaluates to \code{TRUE} and removed otherwise. If you find #' yourself writing code such as \code{if (test()) addClass(id, cl) else removeClass(id, cl)} #' then you can use \code{toggleClass} instead: \code{toggleClass(id, cl, test())}.\cr\cr #' CSS is a simple way to describe how elements on a web page should be #' displayed (position, colour, size, etc.). You can learn the basics #' at \href{https://www.w3schools.com/css/}{W3Schools}. #' #' @note If you use S4 classes, you should be aware of the fact that both S4 and #' \code{shinyjs} use the \code{removeClass()} function. This means that when using S4, #' it is recommended to use \code{removeCssClass()} from \code{shinyjs}, and to #' use \code{methods::removeClass()} for S4 object. #' #' @param id The id of the element/Shiny tag #' @param class The CSS class to add/remove #' @param condition An optional argument to \code{toggleClass}, see 'Details' below. #' @param selector JQuery selector of the elements to target. Ignored if the \code{id} #' argument is given. For example, to add a certain class to all inputs with class x, #' use \code{selector = "input.x"} #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}}, #' \code{\link[shinyjs]{inlineCSS}}, #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' # Add a CSS class for red text colour #' inlineCSS(list(.red = "background: red")), #' actionButton("btn", "Click me"), #' p(id = "element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Change the following line for more examples #' toggleClass("element", "red") #' }) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' toggleClass(class = "red", id = "element") #' addClass("element", "red") #' removeClass("element", "red") #' } #' #' ## toggleClass can be given an optional `condition` argument, which #' ## determines if to add or remove the class #' if (interactive()) { #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' inlineCSS(list(.red = "background: red")), #' checkboxInput("checkbox", "Make it red"), #' p(id = "element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observe({ #' toggleClass(id = "element", class = "red", #' condition = input$checkbox) #' }) #' } #' ) #' } #' @name classFuncs NULL #' @export #' @rdname classFuncs addClass <- function(id = NULL, class = NULL, selector = NULL, asis = FALSE) { fxn <- "addClass" params <- list(id = id, class = class, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname classFuncs addCssClass <- addClass #' @export #' @rdname classFuncs removeClass <- function(id = NULL, class = NULL, selector = NULL, asis = FALSE) { fxn <- "removeClass" params <- list(id = id, class = class, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname classFuncs removeCssClass <- removeClass #' @export #' @rdname classFuncs toggleClass <- function(id = NULL, class = NULL, condition = NULL, selector = NULL, asis = FALSE) { fxn <- "toggleClass" params <- list(id = id, class = class, condition = condition, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname classFuncs toggleCssClass <- toggleClass shinyjs/R/jsFunc-messageFuncs.R 0000644 0001762 0000144 00000003443 15104020675 016142 0 ustar ligges users #' Show a message #' #' \code{alert} (and its alias \code{info}) shows a message to the user as a #' simple popup.\cr\cr #' \code{logjs} writes a message to the JavaScript console. \code{logjs} is #' mainly used for debugging purposes as a way to non-intrusively print #' messages, but it is also visible to the user if they choose to inspect the #' console. You can also use the \code{\link[shinyjs]{showLog}} function to #' print the JavaScript message directly to the R console. #' #' @param text The message to show. Can be either simple text or an R object. #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}}, #' \code{\link[shinyjs]{showLog}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Change the following line for more examples #' alert(paste0("The date is ", date())) #' }) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' alert("Hello!") #' alert(text = R.Version()) #' logjs(R.Version()) #' } #' @name messageFuncs NULL #' @export #' @rdname messageFuncs alert <- function(text) { fxn <- "alert" params <- list(text = text) jsFuncHelper(fxn, params) } #' @export #' @rdname messageFuncs info <- alert #' @export #' @rdname messageFuncs logjs <- function(text) { fxn <- "logjs" params <- list(text = text) jsFuncHelper(fxn, params) } shinyjs/R/reset.R 0000644 0001762 0000144 00000013045 15131777537 013432 0 ustar ligges users #' Reset input elements to their original values #' #' Reset any input element back to its original value. You can either reset #' one specific input at a time by providing the id of a shiny input, or reset #' all inputs within an HTML tag by providing the id of an HTML tag.\cr\cr #' Reset can be performed on any traditional Shiny input widget, which #' includes: textInput, numericInput, sliderInput, selectInput, #' selectizeInput, radioButtons, dateInput, dateRangeInput, checkboxInput, #' checkboxGroupInput, colourInput, passwordInput, textAreaInput. Note that #' \code{actionButton} is not supported, meaning that you cannot reset #' the value of a button back to 0. #' #' @param id The id of the input element to reset or the id of an HTML #' tag to reset all inputs inside it. If no id is provided, then #' all inputs on the page are reset. #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' div( #' id = "form", #' textInput("name", "Name", "Dean"), #' radioButtons("gender", "Gender", c("Male", "Female")), #' selectInput("letter", "Favourite letter", LETTERS) #' ), #' actionButton("resetAll", "Reset all"), #' actionButton("resetName", "Reset name"), #' actionButton("resetGender", "Reset Gender"), #' actionButton("resetLetter", "Reset letter") #' ), #' server = function(input, output) { #' observeEvent(input$resetName, { #' reset("name") #' }) #' observeEvent(input$resetGender, { #' reset("gender") #' }) #' observeEvent(input$resetLetter, { #' reset("letter") #' }) #' observeEvent(input$resetAll, { #' reset("form") #' }) #' } #' ) #' } #' @export reset <- function(id = "", asis = FALSE) { # get the Shiny session session <- getSession() # Make sure reset works with namespaces (shiny modules) nsName <- "" if (id != "" && inherits(session, "session_proxy") && !asis) { id <- session$ns(id) nsName <- session$ns("") } # send a call to JavaScript to figure out what elements to reset and what # values to reset them to shinyInputId <- paste0("shinyjs-resettable-", id) shinyInputIdJs <- shinyInputId if (inherits(session, "session_proxy")) { shinyInputIdJs <- session$ns(shinyInputIdJs) } session$sendCustomMessage("shinyjs-reset", list(id = id, shinyInputId = shinyInputIdJs)) # listen for a response from javascript shiny::observeEvent(session$input[[shinyInputId]], once = TRUE, { messages <- session$input[[shinyInputId]] # go through each input element that javascript told us about and call # the corresponding shiny::updateFooInput() with the correct arguments lapply( names(messages), function(x) { type <- messages[[x]][['type']] value <- messages[[x]][['value']] # password inputs don't have an updatePasswordInput, they use text if (type == "Password") { type <- "Text" } updateFunc <- sprintf("update%sInput", type) # Make sure reset works with namespecing (shiny modules) id <- x if (substring(id, 1, nchar(nsName)) == nsName) { id <- substring(id, nchar(nsName) + 1) } if (inherits(session, "session_proxy") && asis) { session_to_reset <- .subset2(session, "parent") } else { session_to_reset <- session } funcParams <- list(session_to_reset, id) # checkbox values need to be manually converted to TRUE/FALSE if (type == "Checkbox") { value <- as.logical(value) } if (type == "Date") { if (value == "NA") { value <- NA } } # most input update functions use 'value' argument, some use 'selected', # DateRange uses 'start' and 'end' if (type == "RadioButtons") { funcParams[['selected']] <- value } else if (type == "CheckboxGroup" || type == "Select") { if (value == '""') { funcParams[['selected']] <- "" } else { funcParams[['selected']] <- jsonlite::fromJSON(value) } } else if (type == "Slider") { value <- unlist(strsplit(value, ",")) funcParams[['value']] <- value } else if (type == "DateRange") { dates <- unlist(strsplit(value, ",")) dates[dates == "NA"] <- NA funcParams[['start']] <- dates[1] funcParams[['end']] <- dates[2] } else { funcParams[['value']] <- value } # radio buttons don't follow the regular shiny input naming conventions if (type == "RadioButtons") { updateFunc <- sprintf("update%s", type) } # for colour inputs, need to use the colourpicker package if (type == "Colour") { updateFunc <- utils::getFromNamespace(updateFunc, "colourpicker") } # update the input to its original values do.call(updateFunc, funcParams) } ) }) invisible(NULL) } shinyjs/R/jsFunc-stateFuncs.R 0000644 0001762 0000144 00000007432 15131777537 015660 0 ustar ligges users #' Enable/disable an input element #' #' Enable or disable an input element. A disabled element is not usable and #' not clickable, while an enabled element (default) can receive user input. #' Any shiny input tag can be used with these functions.\cr\cr #' \strong{\code{enable}} enables an input, \strong{\code{disable}} disabled #' an input,\strong{\code{toggleState}} enables an input if it is disabled #' and disables an input if it is already enabled.\cr\cr #' If \code{condition} is given to \code{toggleState}, that condition will be used #' to determine if to enable or disable the input. The element will be enabled if #' the condition evaluates to \code{TRUE} and disabled otherwise. If you find #' yourself writing code such as \code{if (test()) enable(id) else disable(id)} #' then you can use \code{toggleState} instead: \code{toggleState(id, test())}. #' #' @param id The id of the input element/Shiny tag #' @param condition An optional argument to \code{toggleState}. The element will #' be enabled when the \code{condition} is \code{TRUE}, and disabled otherwise. #' @param selector Query selector of the elements to target. Ignored if the \code{id} #' argument is given. For example, to disable all text inputs, use #' \code{selector = "input[type='text']"} #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' \code{\link[shinyjs]{disabled}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' textInput("element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Change the following line for more examples #' toggleState("element") #' }) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' toggleState(id = "element") #' enable("element") #' disable("element") #' #' # Similarly, the "element" text input can be changed to many other #' # input tags, such as the following examples #' actionButton("element", "I'm a button") #' fileInput("element", "Choose a file") #' selectInput("element", "I'm a select box", 1:10) #' } #' #' ## toggleState can be given an optional `condition` argument, which #' ## determines if to enable or disable the input #' if (interactive()) { #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' textInput("text", "Please type at least 3 characters"), #' actionButton("element", "Submit") #' ), #' server = function(input, output) { #' observe({ #' toggleState(id = "element", condition = nchar(input$text) >= 3) #' }) #' } #' ) #' } #' @name stateFuncs NULL #' @export #' @rdname stateFuncs enable <- function(id = NULL, selector = NULL, asis = FALSE) { fxn <- "enable" params <- list(id = id, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname stateFuncs disable <- function(id = NULL, selector = NULL, asis = FALSE) { fxn <- "disable" params <- list(id = id, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname stateFuncs toggleState <- function(id = NULL, condition = NULL, selector = NULL, asis = FALSE) { fxn <- "toggleState" params <- list(id = id, condition = condition, selector = selector, asis = asis) jsFuncHelper(fxn, params) } shinyjs/R/extendShinyjs.R 0000644 0001762 0000144 00000025635 15131777537 015157 0 ustar ligges users #' Extend shinyjs by calling your own JavaScript functions #' #' Add your own JavaScript functions that can be called from R as if they were #' regular R functions. This is a more advanced technique and can only #' be used if you know JavaScript. See 'Basic Usage' below for more information #' or \href{https://deanattali.com/shinyjs/}{view the shinyjs webpage} #' to learn more. #' #' @param script Path to a JavaScript file that contains all the functions. #' Each function name must begin with "`shinyjs.`", for example #' "`shinyjs.myfunc`". Note that the path to the file must be discoverable by the browser #' (meaning that it needs to be in a "www/" directory or available via `addResourcePath()`). #' See 'Basic Usage' below for more details. #' @param text Inline JavaScript code to use instead of providing a file. #' See 'Basic Usage' below. #' @param functions The names of the shinyjs JavaScript functions which are defined and #' you want to be able to call using \code{shinyjs}. For example, if you defined JavaScript functions #' named \code{shinyjs.foo} and \code{shinyjs.bar}, then use \code{functions = c("foo", "bar")}. #' #' @section Basic Usage: #' Any JavaScript function defined in your script that begins with "`shinyjs.`" #' and that's provided in the `functions` argument will be available to run #' from R using the "`js$`" variable. For example, if you write a JavaScript function #' called "`shinyjs.myfunc`" and used `functions = c("myfunc")`, then you can call it #' from R with `js$myfunc()`. #' #' It's recommended to write JavaScript code in a separate file and provide the #' filename as the \code{script} argument, but it's also possible to use the #' \code{text} argument to provide a string containing valid JavaScript code. #' #' Here is a basic example of using \code{extendShinyjs()} #' to define a function that changes the colour of the page: #' #' \preformatted{ #' library(shiny) #' library(shinyjs) #' #' jsCode <- "shinyjs.pageCol = function(params){$('body').css('background', params);}" #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' extendShinyjs(text = jsCode, functions = c("pageCol")), #' selectInput("col", "Colour:", #' c("white", "yellow", "red", "blue", "purple")) #' ), #' server = function(input, output) { #' observeEvent(input$col, { #' js$pageCol(input$col) #' }) #' } #' ) #' } #' #' You can add more functions to the JavaScript code, but remember that every #' function you want to use in R has to have a name beginning with #' "`shinyjs.`". See the section on passing arguments and the examples below #' for more information on how to write effective functions. #' #' @section Running JavaScript code on page load: #' If there is any JavaScript code that you want to run immediately when the page loads, #' you can place it inside a \code{shinyjs.init} function. The function \code{shinyjs.init} #' will automatically be called when the Shiny app's HTML is initialized. A common #' use for this is when registering event handlers or initializing JavaScript objects, #' as these usually just need to run once when the page loads. The `functions` parameter #' does not need to be told about the `init` function, so you can use an empty list #' such as `functions = c()` (or if you have an init function together with other shinyjs #' functions, simply list all the functions except for `init`). #' #' For example, the following example uses \code{shinyjs.init} to register an event #' handler so that every keypress will print its corresponding key code: #' #' \preformatted{ #' jscode <- " #' shinyjs.init = function() { #' $(document).keypress(function(e) { alert('Key pressed: ' + e.which); }); #' }" #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' extendShinyjs(text = jscode, functions = c()), #' "Press any key" #' ), #' server = function(input, output) {} #' ) #' } #' #' @section Passing arguments from R to JavaScript: #' Any \code{shinyjs} function that is called will pass a single array-like #' parameter to its corresponding JavaScript function. If the function in R was #' called with unnamed arguments, then it will pass an Array of the arguments; #' if the R arguments are named then it will pass an Object with key-value pairs. #' #' For example, calling \code{js$foo("bar", 5)} in R will call \code{shinyjs.foo(["bar", 5])} #' in JS, while calling \code{js$foo(num = 5, id = "bar")} in R will call #' \code{shinyjs.foo({num : 5, id : "bar"})} in JS. This means that the #' \code{shinyjs.foo} function needs to be able to deal with both types of #' parameters. #' #' To assist in normalizing the parameters, \code{shinyjs} provides a #' \code{shinyjs.getParams()} function which serves two purposes. First of all, #' it ensures that all arguments are named (even if the R function was called #' without names). Secondly, it allows you to define default values for arguments. #' #' Here is an example of a JS function that changes the background colour of an #' element and uses \code{shinyjs.getParams()}. #' #' \preformatted{ #' shinyjs.backgroundCol = function(params) { #' var defaultParams = { #' id : null, #' col : "red" #' }; #' params = shinyjs.getParams(params, defaultParams); #' #' var el = $("#" + params.id); #' el.css("background-color", params.col); #' } #' } #' #' Note the \code{defaultParams} object that was defined and the call to #' \code{shinyjs.getParams}. It ensures that calling \code{js$backgroundCol("test", "blue")} #' and \code{js$backgroundCol(id = "test", col = "blue")} and #' \code{js$backgroundCol(col = "blue", id = "test")} are all equivalent, and #' that if the colour parameter is not provided then "red" will be the default. #' #' All the functions provided in \code{shinyjs} make use of \code{shinyjs.getParams}, #' and it is highly recommended to always use it in your functions as well. #' Notice that the order of the arguments in \code{defaultParams} in the #' JavaScript function matches the order of the arguments when calling the #' function in R with unnamed arguments. #' #' See the examples below for a shiny app that uses this JS function. #' @return Scripts that are required by \code{shinyjs}. #' @note You still need to call \code{useShinyjs()} as usual, and the call to #' \code{useShinyjs()} must come before the call to \code{extendShinyjs()}. #' @seealso \code{\link[shinyjs]{runExample}} #' @examples #' \dontrun{ #' # Example 1: #' # Change the page background to a certain colour when a button is clicked. #' #' jsCode <- "shinyjs.pageCol = function(params){$('body').css('background', params);}" #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' extendShinyjs(text = jsCode, functions = c("pageCol")), #' selectInput("col", "Colour:", #' c("white", "yellow", "red", "blue", "purple")) #' ), #' server = function(input, output) { #' observeEvent(input$col, { #' js$pageCol(input$col) #' }) #' } #' ) #' #' # ============== #' #' # Example 2: #' # Change the background colour of an element, using "red" as default #' #' jsCode <- ' #' shinyjs.backgroundCol = function(params) { #' var defaultParams = { #' id : null, #' col : "red" #' }; #' params = shinyjs.getParams(params, defaultParams); #' #' var el = $("#" + params.id); #' el.css("background-color", params.col); #' }' #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' extendShinyjs(text = jsCode, functions = c("backgroundCol")), #' p(id = "name", "My name is Dean"), #' p(id = "sport", "I like soccer"), #' selectInput("col", "Colour", #' c("green", "yellow", "red", "blue", "white")), #' selectInput("selector", "Element", c("sport", "name", "button")), #' actionButton("button", "Go") #' ), #' server = function(input, output) { #' observeEvent(input$button, { #' js$backgroundCol(input$selector, input$col) #' }) #' } #' ) #' #' # ============== #' #' # Example 3: #' # Create an `increment` function that increments the number inside an HTML #' # tag (increment by 1 by default, with an optional parameter). Use a separate #' # file instead of providing the JS code in a string. #' #' # Create a JavaScript file "myfuncs.js" in a "www/" directory: #' shinyjs.increment = function(params) { #' var defaultParams = { #' id : null, #' num : 1 #' }; #' params = shinyjs.getParams(params, defaultParams); #' #' var el = $("#" + params.id); #' el.text(parseInt(el.text()) + params.num); #' } #' #' # And a shiny app that uses the custom function we just defined. Note how #' # the arguments can be either passed as named or unnamed, and how default #' # values are set if no value is given to a parameter. #' #' library(shiny) #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' extendShinyjs("myfuncs.js", functions = c("increment")), #' p(id = "number", 0), #' actionButton("add", "js$increment('number')"), #' actionButton("add5", "js$increment('number', 5)"), #' actionButton("add10", "js$increment(num = 10, id = 'number')") #' ), #' server = function(input, output) { #' observeEvent(input$add, { #' js$increment('number') #' }) #' observeEvent(input$add5, { #' js$increment('number', 5) #' }) #' observeEvent(input$add10, { #' js$increment(num = 10, id = 'number') #' }) #' } #' ) #' } #' @export extendShinyjs <- function(script, text, functions) { if (missing(script) && missing(text)) { errMsg("extendShinyjs: Either `script` or `text` need to be provided.") } if (missing(functions)) { errMsg("extendShinyjs: `functions` argument must be provided. See the documentation for `?extendShinyjs` for more details.") } isShinyjsFunction <- functions %in% shinyjsFunctionNames("all") if (any(isShinyjsFunction)) { errMsg(paste0( "extendShinyjs: `functions` argument must not contain any of the ", "following function names:\n", paste(functions[isShinyjsFunction], collapse = ", ") )) } jsFuncs <- functions # add all the given functions to the shinyjs namespace so that they can be # called as if they were regular shinyjs functions lapply(jsFuncs, function(x) { assign(x, jsFunc, js) }) # set up the message handlers for all functions setupJS(jsFuncs, script, text) } #' Call user-defined JavaScript functions from R #' @seealso \code{\link[shinyjs]{extendShinyjs}} #' @export #' @keywords internal js <- new.env() shinyjs/R/shinyjs-package.R 0000644 0001762 0000144 00000000563 15132004023 015337 0 ustar ligges users #' @keywords internal "_PACKAGE" #' Defunct functions in shinyjs #' #' - **colourInput()** Moved to the \{colourpicker\} package #' - **updateColourInput()** Moved to the \{colourpicker\} package #' - **colourPicker()** Moved to the \{colourpicker\} package #' - **runExample()** Use `shiny::runExample(package = "shinyjs")` #' #' @name shinyjs-defunct NULL shinyjs/R/runcode.R 0000644 0001762 0000144 00000011354 15131777537 013750 0 ustar ligges users #' Construct to let you run arbitrary R code live in a Shiny app #' #' Sometimes when developing a Shiny app, it's useful to be able to run some R #' code on-demand. This construct provides your app with a text input where you #' can enter any R code and run it immediately.\cr\cr #' This can be useful for testing #' and while developing an app locally, but it \strong{should not be included in #' an app that is accessible to other people}, as letting others run arbitrary R #' code can open you up to security attacks.\cr\cr #' To use this construct, you must add a call to \code{runcodeUI()} in the UI #' of your app, and a call to \code{runcodeServer()} in the server function. You #' also need to initialize shinyjs with a call to \code{useShinyjs()} in the UI. #' #' @note You can only have one \code{runcode} construct in your shiny app. #' Calling this function multiple times within the same app will result in #' unpredictable behaviour. #' #' @param code The initial R code to show in the text input when the app loads #' @param type One of \code{"text"} (default), \code{"textarea"}, or \code{"ace"}. #' When using a text input, the R code will be limited to be typed within a single line, #' and is the recommended option. Textarea should be used if you want to write #' long multi-line R code. Note that you can run multiple expressions even in #' a single line by appending each R expression with a semicolon. #' Use of the \code{"ace"} option requires the \code{shinyAce} package. #' @param width The width of the editable code input (ignored when #' \code{type="ace"}) #' @param height The height of the editable code input (ignored when #' \code{type="text"}) #' @param includeShinyjs Deprecated. You should always make sure to initialize #' shinyjs using \code{\link[shinyjs]{useShinyjs}}. #' @param id When used inside a shiny module, the module's id needs to be #' provided to \code{runcodeUI}. This argument should remain \code{NULL} #' when not used inside a module. #' @seealso \code{\link[shinyjs]{useShinyjs}} #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' runcodeUI(code = "shinyjs::alert('Hello!')") #' ), #' server = function(input, output) { #' runcodeServer() #' } #' ) #' } #' @name runcode #' @rdname runcode #' @export runcodeUI <- function(code = "", type = c("text", "textarea", "ace"), width = NULL, height = NULL, includeShinyjs = NULL, id = NULL) { ns <- shiny::NS(id) if (!missing(includeShinyjs)) { warning("`includeShinyjs` argument is deprecated. You should always make ", "sure to initialize shinyjs using `useShinyjs()`.") } type <- match.arg(type) if (type == "ace") { if (!requireNamespace("shinyAce", quietly = TRUE)) { errMsg("You need to install the 'shinyAce' package in order to use 'shinyAce' editor.") } } placeholder <- "Enter R code" shiny::singleton(shiny::tagList( if (type == "text") shiny::textInput( ns("runcode_expr"), label = NULL, value = code, width = width, placeholder = placeholder ), if (type == "textarea") shiny::textAreaInput( ns("runcode_expr"), label = NULL, value = code, width = width, height = height, placeholder = placeholder ), if (type == "ace") shinyAce::aceEditor(ns("runcode_expr"), mode = 'r', value = code, height = height, theme = "github", fontSize = 16), shiny::actionButton(ns("runcode_run"), "Run", class = "btn-success"), shinyjs::hidden( shiny::div( id = ns("runcode_error"), style = "color: red; font-weight: bold;", shiny::div("Oops, that resulted in an error! Try again."), shiny::div("Error: ", shiny::br(), shiny::tags$i(shiny::span( id = ns("runcode_errorMsg"), style = "margin-left: 10px;"))) ) ) )) } #' @rdname runcode #' @export runcodeServer <- function() { # evaluate expressions in the caller's environment parentFrame <- parent.frame(1) # get the Shiny session session <- getSession() shiny::observeEvent(session$input[['runcode_run']], { shinyjs::hide("runcode_error") tryCatch( shiny::isolate( eval(parse(text = session$input[['runcode_expr']]), envir = parentFrame) ), error = function(err) { shinyjs::html("runcode_errorMsg", as.character(err$message)) shinyjs::show(id = "runcode_error", anim = TRUE, animType = "fade") } ) }) invisible(NULL) } shinyjs/R/jsFunc-click.R 0000644 0001762 0000144 00000002304 15104020675 014577 0 ustar ligges users #' Click on a Shiny button #' #' The \code{click()} function can be used to programatically simulate a click #' on a Shiny \code{actionButton()}. #' #' @param id The id of the button #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' "Count:", textOutput("number", inline = TRUE), br(), #' actionButton("btn", "Click me"), br(), #' "The button will be pressed automatically every 3 seconds" #' ), #' server = function(input, output) { #' output$number <- renderText({ #' input$btn #' }) #' observe({ #' click("btn") #' invalidateLater(3000) #' }) #' } #' ) #' } #' @export click <- function(id, asis = FALSE) { fxn <- "click" params <- list(id = id, asis = asis) jsFuncHelper(fxn, params) } shinyjs/R/useShinyjs.R 0000644 0001762 0000144 00000007176 15131777537 014464 0 ustar ligges users #' Set up a Shiny app to use shinyjs #' #' This function must be called from a Shiny app's UI in order for all other #' \code{shinyjs} functions to work.\cr\cr #' You can call \code{useShinyjs()} from anywhere inside the UI, as long as the #' final app UI contains the result of \code{useShinyjs()}. #' #' If you're a package author and including \code{shinyjs} in a function in your #' your package, you need to make sure \code{useShinyjs()} is called either by #' the end user's Shiny app or by your function's UI. #' #' @param rmd Set this to \code{TRUE} only if you are using \code{shinyjs} #' inside an interactive R markdown document. If using this option, view the #' \href{https://github.com/daattali/shinyjs}{README} online to learn how to #' use shinyjs in R markdown documents. #' @param debug Set this to \code{TRUE} if you want to see detailed debugging #' statements in the JavaScript console. Can be useful when filing bug reports #' to get more information about what is going on. #' @param html Set this to \code{TRUE} only if you are using \code{shinyjs} in #' a Shiny app that builds the entire user interface with a custom HTML file. If #' using this option, view the #' \href{https://github.com/daattali/shinyjs}{README} online to learn #' how to use shinyjs in these apps. #' @return Scripts that \code{shinyjs} requires that are automatically inserted #' to the app's \code{} tag. A side effect of calling this function is that #' a \code{shinyjs} directory is added as a resource path using #' [shiny::addResourcePath()]. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' textInput("element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Run a simply shinyjs function #' toggle("element") #' }) #' } #' ) #' } #' @seealso \code{\link[shinyjs]{runExample}} #' \code{\link[shinyjs]{extendShinyjs}} #' @export useShinyjs <- function(rmd = FALSE, debug = FALSE, html = FALSE) { stopifnot(rmd == TRUE || rmd == FALSE) stopifnot(debug == TRUE || debug == FALSE) stopifnot(html == TRUE || html == FALSE) # `astext` is FALSE in normal shiny apps where the shinyjs content is returned # as a shiny tag that gets rendered by the Shiny UI, and TRUE in interactive # Rmarkdown documents or in Shiny apps where the user builds the entire UI # manually with HTML, because in those cases the content of shinyjs needs to # be returned as plain text that can be added to the HTML .globals$astext <- rmd || html # inject is TRUE when the user builds the entire UI manually with HTML, # because in that case the shinyjs content needs to be injected into the page # using JavaScript .globals$inject <- html # all the default shinyjs methods that should be forwarded to javascript jsFuncs <- shinyjsFunctionNames("core") # grab the file with all the default shinyjs javascript functions shiny::addResourcePath("shinyjs", system.file("srcjs", package = "shinyjs")) jsFile <- file.path("shinyjs", "shinyjs-default-funcs.js") # JavaScript to include to turn debug mode on/off (used for seeing more messages) if (debug) { initJS <- "shinyjs.debug = true;" } else { initJS <- "shinyjs.debug = false;" } # include CSS for hiding elements initCSS <- inlineCSS(".shinyjs-hide { display: none !important; }") # set up the message handlers and add some initial JS and CSS setupJS(jsFuncs, jsFile, initJS, initCSS) } shinyjs/R/globals.R 0000644 0001762 0000144 00000000137 15131777537 013731 0 ustar ligges users # A scope where we can put mutable global variables .globals <- new.env(parent = emptyenv()) shinyjs/R/jsFunc-visibilityFuncs.R 0000644 0001762 0000144 00000011621 15104020675 016702 0 ustar ligges users #' Display/hide an element #' #' Display or hide an HTML element.\cr\cr #' \strong{\code{show}} makes an element visible, \strong{\code{hide}} makes #' an element invisible, \strong{\code{toggle}} displays the element if it it #' hidden and hides it if it is visible.\cr\cr #' \strong{\code{showElement}}, \strong{\code{hideElement}}, and #' \strong{\code{toggleElement}} are synonyms that may be safer to use if you're #' working with S4 classes (since they don't mask any existing S4 functions).\cr\cr #' If \code{condition} is given to \code{toggle}, that condition will be used #' to determine if to show or hide the element. The element will be shown if the #' condition evaluates to \code{TRUE} and hidden otherwise. If you find #' yourself writing code such as \code{if (test()) show(id) else hide(id)} #' then you can use \code{toggle} instead: \code{toggle(id = id, condition = test())}. #' #' If you want to hide/show an element in a few seconds rather than immediately, #' you can use the \code{\link[shinyjs]{delay}} function. #' #' @note If you use S4 classes, you should be aware of the fact that both S4 and #' \code{shinyjs} use the \code{show()} function. This means that when using S4, #' it is recommended to use \code{showElement()} from \code{shinyjs}, and to #' use \code{methods::show()} for S4 object. #' #' @param id The id of the element/Shiny tag #' @param anim If \code{TRUE} then animate the behaviour #' @param animType The type of animation to use, either \code{"slide"} or \code{"fade"} #' @param time The number of seconds to make the animation last #' @param selector JQuery selector of the elements to show/hide. Ignored if the #' \code{id} argument is given. For example, to select all span elements with #' class x, use \code{selector = "span.x"} #' @param condition An optional argument to \code{toggle}, see 'Details' below. #' @param asis If \code{TRUE}, use the ID as-is even when inside a module #' (instead of adding the namespace prefix to the ID). #' @seealso \code{\link[shinyjs]{useShinyjs}}, #' \code{\link[shinyjs]{runExample}}, #' \code{\link[shinyjs]{hidden}}, #' \code{\link[shinyjs]{delay}} #' @note \code{shinyjs} must be initialized with a call to \code{useShinyjs()} #' in the app's ui. #' @examples #' if (interactive()) { #' library(shiny) #' #' shinyApp( #' ui = fluidPage( #' useShinyjs(), # Set up shinyjs #' actionButton("btn", "Click me"), #' textInput("text", "Text") #' ), #' server = function(input, output) { #' observeEvent(input$btn, { #' # Change the following line for more examples #' toggle("text") #' }) #' } #' ) #' } #' \dontrun{ #' # The shinyjs function call in the above app can be replaced by #' # any of the following examples to produce similar Shiny apps #' toggle(id = "text") #' delay(1000, toggle(id = "text")) # toggle in 1 second #' toggle("text", TRUE) #' toggle("text", TRUE, "fade", 2) #' toggle(id = "text", time = 1, anim = TRUE, animType = "slide") #' show("text") #' show(id = "text", anim = TRUE) #' hide("text") #' hide(id = "text", anim = TRUE) #' } #' #' ## toggle can be given an optional `condition` argument, which #' ## determines if to show or hide the element #' if (interactive()) { #' shinyApp( #' ui = fluidPage( #' useShinyjs(), #' checkboxInput("checkbox", "Show the text", TRUE), #' p(id = "element", "Watch what happens to me") #' ), #' server = function(input, output) { #' observe({ #' toggle(id = "element", condition = input$checkbox) #' }) #' } #' ) #' } #' @name visibilityFuncs NULL #' @export #' @rdname visibilityFuncs show <- function(id = NULL, anim = FALSE, animType = "slide", time = 0.5, selector = NULL, asis = FALSE) { fxn <- "show" params <- list(id = id, anim = anim, animType = animType, time = time, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname visibilityFuncs showElement <- show #' @export #' @rdname visibilityFuncs hide <- function(id = NULL, anim = FALSE, animType = "slide", time = 0.5, selector = NULL, asis = FALSE) { fxn <- "hide" params <- list(id = id, anim = anim, animType = animType, time = time, selector = selector, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname visibilityFuncs hideElement <- hide #' @export #' @rdname visibilityFuncs toggle <- function(id = NULL, anim = FALSE, animType = "slide", time = 0.5, selector = NULL, condition = NULL, asis = FALSE) { fxn <- "toggle" params <- list(id = id, anim = anim, animType = animType, time = time, selector = selector, condition = condition, asis = asis) jsFuncHelper(fxn, params) } #' @export #' @rdname visibilityFuncs toggleElement <- toggle shinyjs/vignettes/ 0000755 0001762 0000144 00000000000 15132024265 013751 5 ustar ligges users shinyjs/vignettes/shinyjs-extend.Rmd 0000644 0001762 0000144 00000014664 15104020675 017404 0 ustar ligges users --- title: "extendShinyjs: Calling your own JavaScript functions from R" author: "Dean Attali" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{extendShinyjs - Calling your own JavaScript functions from R} %\VignetteEngine{knitr::rmarkdown} %\usepackage[utf8]{inputenc} --- ```{r setup, echo = FALSE, message = FALSE} knitr::opts_chunk$set(tidy = FALSE, comment = "#>") ``` # extendShinyjs: Calling your own JavaScript functions from R