Skip to content

Commit

Permalink
add 'removeEvent' function to remove events attached to elements (closes
Browse files Browse the repository at this point in the history
  • Loading branch information
daattali committed Dec 1, 2021
1 parent 672d100 commit b8c9f3f
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 72 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: 2.0.0.9000
Version: 2.0.0.9001
Authors@R: person("Dean", "Attali",
email = "[email protected]",
role = c("aut", "cre"),
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export(onevent)
export(refresh)
export(removeClass)
export(removeCssClass)
export(removeEvent)
export(reset)
export(runExample)
export(runcodeServer)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased version

- New feature: you can now reset all inputs on the page by calling `reset()` with no arguments (#222)
- New feature: Add a `removeEvent()` function which removes events added to HTML elements with `onclick()` or `onevent()` (#244)
- Fix bug: `disable()` did not work on nested download buttons (#223)
- Fix bug: Don't automatically namespace ID arguments in custom extendShinyjs functions (#229)
- Fix bug: ensure that `extendShinyjs()` functions don't overwrite native {shinyjs} functions (#230)
Expand Down
62 changes: 58 additions & 4 deletions R/onevent.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#' 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}.
#' 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.
Expand All @@ -23,7 +24,10 @@
#' 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).
#' @seealso \code{\link[shinyjs]{useShinyjs}},
#' @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.
Expand All @@ -41,7 +45,7 @@
#' 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 porperties that can be returned is: \code{altKey}, \code{button},
#' 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}.
Expand Down Expand Up @@ -146,5 +150,55 @@ oneventHelper <- function(event, id, expr, add, properties, asis) {
}
})

invisible(NULL)
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)
}
2 changes: 1 addition & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ shinyjsFunctionNames <- function(type = c("all", "core")) {
# core functions are defined in JS and exported in R
jsFuncs <- c(
"show", "hide", "toggle", "enable", "disable", "toggleState",
"addClass", "removeClass", "toggleClass", "html", "onevent",
"addClass", "removeClass", "toggleClass", "html", "onevent", "removeEvent",
"alert", "logjs", "runjs", "reset", "delay", "click", "refresh"
)

Expand Down
97 changes: 36 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
<h3 align="center">

shinyjs

</h3>

<h4 align="center">

Easily improve the user experience of your Shiny apps in seconds
<br><br> <a href="https://deanattali.com/shinyjs/">Official website</a>
· by <a href="https://deanattali.com">Dean Attali</a>

</h4>

<p align="center">

<a href="https://github.com/daattali/shinyjs/actions">
<img src="https://github.com/daattali/shinyjs/workflows/R-CMD-check/badge.svg" alt="R Build Status" />
</a> <a href="https://cran.r-project.org/package=shinyjs">
<img src="https://www.r-pkg.org/badges/version/shinyjs" alt="CRAN version" />
</a> <a href="https://xscode.com/daattali/shinyjs">
<img src="https://img.shields.io/badge/Available%20on-xs%3Acode-blue?style=?style=plastic&logo=appveyor&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////////VXz1bAAAAAJ0Uk5T/wDltzBKAAAAlUlEQVR42uzXSwqAMAwE0Mn9L+3Ggtgkk35QwcnSJo9S+yGwM9DCooCbgn4YrJ4CIPUcQF7/XSBbx2TEz4sAZ2q1RAECBAiYBlCtvwN+KiYAlG7UDGj59MViT9hOwEqAhYCtAsUZvL6I6W8c2wcbd+LIWSCHSTeSAAECngN4xxIDSK9f4B9t377Wd7H5Nt7/Xz8eAgwAvesLRjYYPuUAAAAASUVORK5CYII=" alt="Purchase shinyjs services on xcode" />
</a>

</p>

</p>

-----
------------------------------------------------------------------------

<img src="inst/img/hex.png" width="170" align="right"/>

Expand All @@ -43,14 +34,14 @@ JavaScript functions from R.
**Need Shiny help? [I’m available for
consulting](https://attalitech.com/).**<br/> **If you find {shinyjs}
useful, please consider [supporting my
work](https://github.com/sponsors/daattali) to unlock rewards\!**
work](https://github.com/sponsors/daattali) to unlock rewards! ❤**

<p align="center">

<a style="display: inline-block; margin-left: 10px;" href="https://github.com/sponsors/daattali">
<img height="35" src="https://i.imgur.com/034B8vq.png" /> </a>

<a style="display: inline-block;" href="https://paypal.me/daattali">
<a style="display: inline-block;" href="https://www.paypal.com/donate/?hosted_button_id=DG8NNBJHRKM46">
<img height="35" src="https://camo.githubusercontent.com/0e9e5cac101f7093336b4589c380ab5dcfdcbab0/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f74776f6c66736f6e2f70617970616c2d6769746875622d627574746f6e40312e302e302f646973742f627574746f6e2e737667" />
</a>

Expand Down Expand Up @@ -120,50 +111,44 @@ work](https://github.com/sponsors/daattali) to unlock rewards\! ❤**

# Table of contents

- [Demos and tutorials](#demos)
- [Sponsors 🏆](#sponsors)
- [Overview of main functions](#overview-main)
- [Installation](#install)
- [How to use](#usage)
- [Basic use case - complete working example](#usecase)
- [Calling your own JavaScript functions from R](#extendshinyjs)
- [FAQ and extra tricks](#faq-tricks)
- [Support](#support)
- [Demos and tutorials](#demos)
- [Sponsors 🏆](#sponsors)
- [Overview of main functions](#overview-main)
- [Installation](#install)
- [How to use](#usage)
- [Basic use case - complete working example](#usecase)
- [Calling your own JavaScript functions from R](#extendshinyjs)
- [FAQ and extra tricks](#faq-tricks)
- [Support](#support)

<h2 id="demos">

Demos and tutorials

</h2>

- [Demo Shiny app](https://deanattali.com/shinyjs/demo) that lets you
- [Demo Shiny app](https://deanattali.com/shinyjs/demo) that lets you
play around with some of the functionality in {shinyjs}.
- [Video of my {shinyjs}
- [Video of my {shinyjs}
talk](https://deanattali.com/shinyjs-shinydevcon-2016/) (30 min) and
the corresponding [presentation
slides](https://bit.ly/shinyjs-slides) from the 2016 Shiny Developer
Conference.
- [Video of my {shinyjs}
- [Video of my {shinyjs}
talk](https://deanattali.com/shinyjs-user-2016/) (5 min) and the
corresponding [presentation
slides](https://bit.ly/shinyjs-slides-useR2016) from the 2016 useR
Conference.

<h2 id="sponsors">

Sponsors 🏆

</h2>

> There are no sponsors yet
[Become the first sponsor for {shinyjs} and unlock special
rewards\!](https://github.com/sponsors/daattali/sponsorships?tier_id=39856)
rewards!](https://github.com/sponsors/daattali/sponsorships?tier_id=39856)

<h2 id="overview-main">

Overview of main functions

</h2>

**Note: In order to use any {shinyjs} function in a Shiny app, you must
Expand Down Expand Up @@ -230,14 +215,18 @@ first call `useShinyjs()` anywhere in the app’s UI.**
<td>Similar to <code>onclick</code>, but can be used with many other events instead of click (for example, listen for a key press, mouse hover, etc).</td>
</tr>
<tr class="odd">
<td><code>removeEvent</code></td>
<td>Remove an event that was added to an HTML element with <code>onclick()</code> or <code>onevent()</code>.</td>
</tr>
<tr class="even">
<td><code>addClass</code>/<code>removeClass</code>/<code>toggleClass</code></td>
<td>add or remove a CSS class from an element.</td>
</tr>
<tr class="even">
<tr class="odd">
<td><code>runjs</code></td>
<td>Run arbitrary JavaScript code.</td>
</tr>
<tr class="odd">
<tr class="even">
<td><code>extendShinyjs</code></td>
<td>Allows you to write your own JavaScript functions and use {shinyjs} to call them as if they were regular R code. More information is available in the section “Calling your own JavaScript functions from R” below.</td>
</tr>
Expand Down Expand Up @@ -282,9 +271,7 @@ to see some of these in action, or install {shinyjs} and run
`shinyjs::runExample()` to see more demos.

<h2 id="install">

Installation

</h2>

To install the stable CRAN version:
Expand All @@ -297,9 +284,7 @@ To install the latest development version from GitHub:
remotes::install_github("daattali/shinyjs")

<h2 id="usage">

How to use

</h2>

A typical Shiny app has a UI portion and a server portion. Before using
Expand All @@ -310,31 +295,31 @@ Here is a minimal Shiny app that uses {shinyjs}:

library(shiny)
library(shinyjs)

ui <- fluidPage(
useShinyjs(), # Include shinyjs

actionButton("button", "Click me"),
textInput("text", "Text")
)

server <- function(input, output) {
observeEvent(input$button, {
toggle("text") # toggle is a shinyjs function
})
}

shinyApp(ui, server)

This is how most Shiny apps should initialize {shinyjs} - by calling
`useShinyjs()` near the top of the UI.

However, if you use {shinyjs} in any of the following cases:

- In Shiny dashboards (built using the `shinydashboard` package)
- In Shiny apps that use a `navbarPage` layout
- In Rmd documents
- In Shiny apps that manually build the user interface with an HTML
- In Shiny dashboards (built using the `shinydashboard` package)
- In Shiny apps that use a `navbarPage` layout
- In Rmd documents
- In Shiny apps that manually build the user interface with an HTML
file or template (instead of using Shiny’s UI functions)

Then you should see the [*Including {shinyjs} in different types of
Expand All @@ -345,9 +330,7 @@ above code sample should be enough to get your started with including
{shinyjs} in your app.

<h2 id="usecase">

Basic use case - complete working example

</h2>

See the [*{shinyjs} example app
Expand All @@ -356,9 +339,7 @@ step-by-step guide on how to add a variety of {shinyjs} features to a
simple app in order to make it more user friendly.

<h2 id="extendshinyjs">

Calling your own JavaScript functions from R

</h2>

You can also use {shinyjs} to add your own JavaScript functions that can
Expand All @@ -372,37 +353,33 @@ To learn about this feature and see how useful it can be, see the
R*](https://deanattali.com/shinyjs/extend) document.

<h2 id="faq-tricks">

FAQ and extra tricks

</h2>

There are several questions that pop up very frequently in my email or
on StackOverflow about “How do I use {shinyjs} to do \_\_\_?” Here is a
list of a few of these common questions with links to a solution that
could be useful. Note that all of these require using `extendShinyjs()`.

- [How do I show/hide the `shinydashboard` sidebar
- [How do I show/hide the `shinydashboard` sidebar
programmatically?](https://stackoverflow.com/a/31306707/3943160)
- [How do I hide/disable a
- [How do I hide/disable a
tab?](https://stackoverflow.com/a/31719425/3943160)
- [How do I refresh the
- [How do I refresh the
page?](https://stackoverflow.com/a/34758024/3943160)
- [How do I call a JavaScript function from a different JavaScript
- [How do I call a JavaScript function from a different JavaScript
library?](https://github.com/timelyportfolio/sweetalertR/issues/1#issuecomment-151685005)
- [How do I change the values of a
- [How do I change the values of a
`sliderInput`?](https://stackoverflow.com/a/31066997/3943160)
- [How do I call JavaScript code and use the return
- [How do I call JavaScript code and use the return
value?](https://stackoverflow.com/a/34728125/3943160)

I also keep a long [list of various Shiny tips &
tricks](https://deanattali.com/blog/advanced-shiny-tips/) for solving
common Shiny problems, many of which make use of {shinyjs}.

<h2 id="support">

Support

</h2>

This document is only an overview of {shinyjs}. There are more in-depth
Expand All @@ -421,9 +398,7 @@ please visit <https://xscode.com/daattali/shinyjs> or [contact
me](https://attalitech.com/contact).**

<h2>

Credits

</h2>

Logo design by [Alfredo Hernández](https://aldomann.com/).
Loading

0 comments on commit b8c9f3f

Please sign in to comment.