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.
You can install the development version of shinyfocus from GitHub with:
# install.packages("pak")
# pak::pak("shinyworks/shinyfocus")
install.packages("shinyfocus", repos = c('https://shinyworks.r-universe.dev', 'https://cloud.r-project.org'))
I’ve envisioned two primary use cases (although I hope and assume that there are many others):
The app demonstrated here does both.
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!
onevent(), that can be used for similar functionality. However, that
implementation is different than what we do here.Please note that the shinyfocus project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.