An open API service indexing awesome lists of open source software.

https://github.com/shinyworks/shinyfocus

Use Browser Focus Events in 'shiny'
https://github.com/shinyworks/shinyfocus

Last synced: 4 months ago
JSON representation

Use Browser Focus Events in 'shiny'

Awesome Lists containing this project

README

        

---
output: github_document
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```

# shinyfocus

[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[![CRAN status](https://www.r-pkg.org/badges/version/shinyfocus)](https://CRAN.R-project.org/package=shinyfocus)
[![Codecov test coverage](https://codecov.io/gh/shinyworks/shinyfocus/branch/main/graph/badge.svg)](https://app.codecov.io/gh/shinyworks/shinyfocus?branch=main)
[![R-CMD-check](https://github.com/shinyworks/shinyfocus/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/shinyworks/shinyfocus/actions/workflows/R-CMD-check.yaml)

The goal of shinyfocus is to make it easy to trigger server events in {shiny} apps based on elements of the app gaining or losing focus in the browser.

## Installation

You can install the development version of shinyfocus from [GitHub](https://github.com/) with:

``` r
# install.packages("pak")
pak::pak("shinyworks/shinyfocus")
```

## Examples

I've envisioned two primary use cases (although I hope and assume that there are many others):

- Showing help related to an input.
- Validating an input when the user is "done" with an input.

The app demonstrated here does both.

``` r
library(shinyfocus)

ui <- shiny::fluidPage(
shinyfocus_js_dependency(),
shiny::column(
2,
shiny::textInput("name", "Name:"),
shiny::textInput("title", "Title:")
),
shiny::column(
2,
shiny::textOutput("explanation")
)
)

server <- function(input, output, session) {
on_focus(
"name",
output$explanation <- shiny::renderText({
"Enter the name you want me to call you. It will be converted to Title Case."
})
)

on_focus(
"title",
output$explanation <- shiny::renderText({
"Describe your role in 10 characters or fewer."
})
)

on_blur(
"name",
shiny::updateTextInput(
inputId = "name",
value = stringr::str_to_title(shiny::isolate(input$name))
)
)

on_blur(
"title",
{
if (nchar(input$title) > 10) {
shiny::updateTextInput(
inputId = "title",
value = paste(
"Typer of",
nchar(input$title),
"Characters"
)
)
}
}
)

}

shiny::shinyApp(ui, server)
```

Note: I feel like the "explanation" output could be cleaner.
I'd like to find a better way to implement the "explanatin" output, having it switch based on which input is selected (rather than the roundabout double observer).
I hope to update that soon!

## Related Work

- {[shinyjs](https://deanattali.com/shinyjs/)} has a function, `onevent()`, that can be used for similar functionality.
However, that implementation is different than what we do here.

## Code of Conduct

Please note that the shinyfocus project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.