Skip to content

Commit

Permalink
onclick and onevent now support callback functions; fixes #92
Browse files Browse the repository at this point in the history
  • Loading branch information
daattali committed Nov 2, 2016
1 parent 2a8e2ca commit 6e6663d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 9 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: shinyjs
Title: Easily Improve the User Experience of Your Shiny Apps in Seconds
Version: 0.7.9005
Version: 0.7.9006
Authors@R: person("Dean", "Attali", email = "[email protected]",
role = c("aut", "cre"))
Description: Perform common useful JavaScript operations in Shiny apps that will
Expand Down
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# shinyjs 0.7.xxxx

- `onclick` and `onevent` now support callback functions, and the JavaScript Event object is passed to the callback (#92)
- added `runcodeUI()` and `runcodeServer()` functions that you can add to your app in order to run arbitrary R code interactively
- added `showLog()` function which lets you redirect all JavaScript logging statements to the R console, to make it easier and quicker to debug apps without having to open the JS console
- added `showLog()` function which lets you redirect all JavaScript logging statements to the R console, to make it easier and quicker to debug apps without having to open the JS console (#88)
- added `alert()` as an alias for `info()`

# shinyjs 0.7
Expand Down
24 changes: 22 additions & 2 deletions R/onevent.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
#' @param event The event that needs to be triggered to run the code. See below
#' for a list of possible event types.
#' @param id The id of the element/Shiny tag
#' @param expr The R expression to run after the event is triggered
#' @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 details as its argument. Using a function can be useful
#' when you want to know for example what key was pressed on a "keypress" event.
#' @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
Expand All @@ -33,11 +36,13 @@
#' 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"))
#' }
Expand Down Expand Up @@ -94,7 +99,22 @@ oneventHelper <- function(event, id, expr, add) {
# every time the given event occurs
expr <- deparse(expr)
shiny::observeEvent(session$input[[shinyInputId]], {
eval(parse(text = expr), envir = parentFrame)
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(NULL)
Expand Down
21 changes: 17 additions & 4 deletions inst/srcjs/shinyjs-default-funcs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// shinyjs 0.7.9005 by Dean Attali
// shinyjs 0.7.9006 by Dean Attali
// Perform common JavaScript operations in Shiny apps using plain R code

shinyjs = function() {
Expand Down Expand Up @@ -432,19 +432,32 @@ shinyjs = function() {
var attrName = "data-shinyjs-" + params.event;

// if this is the first event handler of this event type we attach to this
// element, initialize the data attribute and add the event handler
// element, initialize the data attribute and add the event handler
var first = !(el[0].hasAttribute(attrName));
if (first) {
el.attr(attrName, JSON.stringify(Object()));

el[params.event](function() {
el[params.event](function(event) {
// Store a subset of the event properties (many are non-serializeable)
var props = ['altKey', 'button', 'buttons', 'clientX', 'clienty',
'ctrlKey', 'pageX', 'pageY', 'screenX', 'screenY', 'shiftKey',
'which', 'charCode', 'key', 'keyCode'];
var eventSimple = {};
$.each(props, function(idx, prop) {
if (prop in event) {
eventSimple[[prop]] = event[[prop]];
}
});
eventSimple.shinyjsRandom = Math.random();

var oldValues = JSON.parse(el.attr(attrName));
var newValues = Object();
$.each(oldValues, function(key, value) {
var newValue = value + 1;
newValues[key] = newValue;
Shiny.onInputChange(key, newValue);
Shiny.onInputChange(key, eventSimple);
});

el.attr(attrName, JSON.stringify(newValues));
});
}
Expand Down
7 changes: 6 additions & 1 deletion man/onevent.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6e6663d

Please sign in to comment.