Using enter key with action button in R Shiny
I was able to figure this out using the jQuery is(":focus")
function, the code I used was:
$(document).keyup(function(event) {
if ($("#number").is(":focus") && (event.key == "Enter")) {
$("#goButton").click();
}
});
Shiny: Using enter key with action button on login screen
For anyone else who stumbles upon this thread, this solution (unlike the accepted solution to the above-linked SO post Using enter key with action button in R Shiny) does not require an external js script file.
The js
script should have been included inside the modalDialog()
instead, and inside the HTML()
function, as follows:
library(shiny)
library(shinydashboard)
Logged = FALSE
my_username <- "test"
my_password <- "test"
js <- '
$(document).keyup(function(event) {
if ($("#password").is(":focus") && (event.keyCode == 13)) {
$("#ok").click();
}
});
'
ui <- dashboardPage(skin = "blue",
dashboardHeader(title = "Dashboard"),
dashboardSidebar(),
dashboardBody("Test",
verbatimTextOutput("dataInfo")
)
)
server = function(input, output, session) {
values <- reactiveValues(authenticated = FALSE)
# Return the UI for a modal dialog with data selection input. If 'failed'
# is TRUE, then display a message that the previous value was invalid.
dataModal <- function(failed = FALSE) {
modalDialog(
tags$script(HTML(js)),
textInput("username", "Username:"),
passwordInput("password", "Password:"),
footer = tagList(
# modalButton("Cancel"),
actionButton("ok", "OK")
)
)
}
# Show modal when button is clicked.
# This `observe` is suspended only whith right user credential
obs1 <- observe({
showModal(dataModal())
})
# When OK button is pressed, attempt to authenticate. If successful,
# remove the modal.
obs2 <- observe({
req(input$ok)
isolate({
Username <- input$username
Password <- input$password
})
Id_username <- which(my_username == Username)
Id_password <- which(my_password == Password)
if (length(Id_username) > 0 & length(Id_password) > 0) {
if (Id_username == Id_password) {
Logged <<- TRUE
values$authenticated <- TRUE
obs1$suspend()
removeModal()
} else {
values$authenticated <- FALSE
}
}
})
output$dataInfo <- renderPrint({
if(values$authenticated){
"OK!!!!!"
} else {
"You are NOT authenticated"
}
})
}
shinyApp(ui,server)
Also, as a side note, I believe that the js script was originally inspired by this example.
Trigger actionButton with keyboard in shiny using uiOutput
This should do:
library(shiny)
jscode <- '$(document).keyup(function(e) {
if (e.key == "Enter") {
$("#user_login").click();
}});'
ui <- fluidPage(
tags$head(tags$script(HTML(jscode))),
uiOutput("ui")
)
server <- function(input, output, session) {
output$ui <- renderUI({
tagList(
tagAppendAttributes(passwordInput("user_pw", "Password",value = ""),`data-proxy-click` = "user_login"
),
actionButton("user_login", "Anmelden")
)
})
observeEvent(input$user_login, {
cat("clicked", "\n")
})
}
shinyApp(ui, server)
Shiny: Action button is not working after clicking enter
You'll have to bind this manually. Try implementing the following, and replace InputId
with the InputId for your actionButton.
$(document).keyup(function(event) {
if(event.keyCode == 13) {
$('#InputId').click();
}
});
Shiny Responds to Enter
In your case, the problem is reactive programming and this is the reason that you need something to manage this situation. My recommendation is to use observer pattern or validate function.
Observer pattern: shiny implements the observer pattern which is
useful to act when an event happens in an object (it can be a click
in a button, new value in an input...).Validate function: the functionality of this process is similar to an
if/else statement. Indeed, there is need what is the if to check the
parameter, if the values are wrong, there will be an error message.
To know how to use observe pattern and the validate function, click on the previous link (in the Shiny website is everything explained).
R Shiny key and actionButton binding to reactive values
The problem is that the input event only captures the keycode of the pressed key, which stays the same once the key is pressed. Shiny however only reacts if the event data changes. You need to set the event data to something new every time; e.g. the current time stamp. Look at this working example:
library(shiny)
shinyApp(ui <- pageWithSidebar(
headerPanel("Test keyboard control"),
sidebarPanel(
tags$script('$(document).on("keydown",
function (e) {
if(e.which == 68) {
Shiny.onInputChange("downButton", new Date());
} else if (e.which == 85) {
Shiny.onInputChange("upButton", new Date());
}
});
'),
actionButton("downButton", "Down"),
actionButton("upButton", "Up")
),
mainPanel(htmlOutput("text"))
),
server <- function(session, input, output) {
vals <- reactiveValues(count = 0)
observeEvent(input$downButton, {vals$count <- vals$count - 1})
observeEvent(input$upButton, {vals$count <- vals$count + 1})
output$text <- renderText(paste("Counter is:", vals$count))
}
)
Making an Action Button re-read file and recompute in Shiny
If I'm reading this right you'd like to spare your query limit by providing a local set of data to your shiny application. But if a user requests an update you'd like to trigger a query to be used in calculations.
I cannot recommend enough that you make full use of reactivity in Shiny. It is fairly rare to use an object from the global environment, especially when you intend for user inputs to manipulate those objects. You should have your base data ( in your case the tsv) load into the global environment, and then call that information into your application via a reactive dataframe
. I built the below minimal example using mpg
subset to the first 5 rows to simulate the .tsv on your local machine. mpg
subset to 10 rows is to simulate the results of a query to a database. These two data sets get called via an if else
statement dependent on an actionbutton
.
library(tidyverse)
library(shiny)
# using partial mpg data to simulate un-updated data
mpg <- ggplot2::mpg[1:5,]
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("update", "Update Data"),
uiOutput('selectOpts')
),
mainPanel(
h2("This is our base data layer"),
verbatimTextOutput('print_interval1'),
h2("This is our output data"),
verbatimTextOutput('print_interval2')
)
)
)
server <- function(input, output) {
# The core of shiny is the reactivity. It's the workhorse of interactive apps.
# If possible, a data calculation should always happen in a reactive context.
working_data <- reactive({
# actionbuttons increment a value by 1, starting with 0. If input < 0 the
# user has not interacted yet. If incremented again, the reactive context
# will invalidate and re-calculate the working_data() object
if (input$update < 1) {
base_dat <-
mpg %>%
mutate(ratio = cty/hwy)
} else {
base_dat <-
ggplot2::mpg[1:10,] %>% # calling from namespace to simulate a query. Full data
mutate(ratio = cty/hwy)
}
# return our base data. Can be called with `working_data()`
data.frame(base_dat)
})
output$print_interval1 <- renderPrint({
working_data()
})
output$selectOpts <- renderUI({
# using the reactive data inside renderUI we can be flexible in our options
# this lets us adapt the UI to reactive data.
radioButtons('model',
"Select Model",
sort(unique(working_data()$model)))
})
# You can also chain reactive objects.
output_data <- reactive({
working_data() %>%
group_by(model) %>%
filter(model == input$model) %>%
summarise(m.ratio = mean(ratio))
})
output$print_interval2 <- renderPrint({
output_data() %>%
data.table()
})
}
shinyApp(ui = ui, server = server)
I also recommend looking into this post about database syncing for setting up triggers and using reactive objects as your applications get more complex. I hope that's enough to get you on the right track for both your initial question about updating data, and your comments about having your inputs react to updated data.
Using action button to set value of widget in R Shiny
Lets make the checkbox be dependant on the current_state()
, we can achieve that with the first observeEvent(current_state(),{...
. The reset part we just update the input$num
using the second observeEvent(input$action, {...
and since the checkbox is already dependant on the current_state()
it will auto reset also...
library(shiny)
test_data <- c(TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE)
original_state <- 4
ui <- fluidPage(
titlePanel("Action Button Test"),
sidebarLayout(
sidebarPanel(
numericInput("num", label = h3("Select Row:"), value = original_state,max = length(test_data)),
actionButton("action", label = "Reset State")
),
mainPanel(
checkboxInput("checkbox", label = "State", value = test_data[original_state])
)
)
)
server <- function(input, output, session) {
current_state <- reactive({
test_data[input$num]
})
observeEvent(current_state(),{
updateCheckboxInput(session, "checkbox", value = current_state())
})
observeEvent(input$action, {
updateNumericInput(session,'num', value = original_state)
})
}
shinyApp(ui = ui, server = server)
Related Topics
Space Filling with Circles of Unequal Size
Applying Classname/Onclick/Onchange Not Working on Custom React Component
How to Wait in Node.Js (Javascript)? L Need to Pause for a Period of Time
JavaScript Es6 Array Feature [...Data, 0] "Spread Operator"
What Is the Lifecycle of an Angularjs Controller
"Cannot Use Import Statement Outside a Module" Error When Importing React-Hook-Mousetrap in Next.Js
Understanding Promises in Node.Js
How to Change the HTML Content as It's Loading on the Page
Where Do the Parameters in a JavaScript Callback Function Come From
Concerns, Decorators, Presenters, Service Objects, Helpers - Help Me Understand Them
What Are Asynchronous Functions in JavaScript? What Is "Async" and "Await" in JavaScript
This' Different Between Repl and Script
Angular 2 Dependency Injection in Es5 and Es6
$.Deferred: How to Detect When Every Promise Has Been Executed