extendShinyjs {shinyjs} | R Documentation |
Extend shinyjs by calling your own JavaScript functions
Description
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 view the shinyjs webpage to learn more.
Usage
extendShinyjs(script, text, functions)
Arguments
script |
Path to a JavaScript file that contains all the functions.
Each function name must begin with " |
text |
Inline JavaScript code to use instead of providing a file. See 'Basic Usage' below. |
functions |
The names of the shinyjs JavaScript functions which are defined and
you want to be able to call using |
Value
Scripts that are required by shinyjs
.
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 script
argument, but it's also possible to use the
text
argument to provide a string containing valid JavaScript code.
Here is a basic example of using extendShinyjs()
to define a function that changes the colour of the page:
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.
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 shinyjs.init
function. The function 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 shinyjs.init
to register an event
handler so that every keypress will print its corresponding key code:
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) {} )
Passing arguments from R to JavaScript
Any 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 js$foo("bar", 5)
in R will call shinyjs.foo(["bar", 5])
in JS, while calling js$foo(num = 5, id = "bar")
in R will call
shinyjs.foo({num : 5, id : "bar"})
in JS. This means that the
shinyjs.foo
function needs to be able to deal with both types of
parameters.
To assist in normalizing the parameters, shinyjs
provides a
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 shinyjs.getParams()
.
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 defaultParams
object that was defined and the call to
shinyjs.getParams
. It ensures that calling js$backgroundCol("test", "blue")
and js$backgroundCol(id = "test", col = "blue")
and
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 shinyjs
make use of shinyjs.getParams
,
and it is highly recommended to always use it in your functions as well.
Notice that the order of the arguments in 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.
Note
You still need to call useShinyjs()
as usual, and the call to
useShinyjs()
must come before the call to extendShinyjs()
.
See Also
Examples
## Not run:
# 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')
})
}
)
## End(Not run)