Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: allow inputs to trigger reactive flow even if the value of input hasn't changed #928

Closed
daattali opened this issue Aug 14, 2015 · 19 comments
Assignees

Comments

@daattali
Copy link
Contributor

daattali commented Aug 14, 2015

Sometimes it's useful to trigger a reactive chain based on an input even if the input's value hasn't changed.

Simple silly example: suppose you have a shiny app with a few tabs and you want the user to be able to switch tabs by typing the corresponding number. For example, press the "2" key to switch to the second tab. Here's a simple implementation that I would want to work

library(shiny)

jscode <- "
$(function(){ 
 $(document).keyup(function(e) {
 if (e.which >= 49 && e.which <= 57) {
 Shiny.onInputChange('numpress', e.which - 48);
 }
 });
})
"

runApp(shinyApp(
 ui = fluidPage(
 tags$script(HTML(jscode)),
 "Type a number to switch to that tab",
 tabsetPanel(
 id = "navbar",
 tabPanel("tab1", "Tab 1"),
 tabPanel("tab2", "Tab 2"),
 tabPanel("tab3", "Tab 3"),
 tabPanel("tab4", "Tab 4")
 )
 ),
 server = function(input, output, session) {
 observe({
 if (is.null(input$numpress)) {
 return()
 }
 updateTabsetPanel(session, "navbar", sprintf("tab%s", input$numpress))
 })
 }
))

If you only switch tabs using the numbers on your keyboard, it works fine. But if you press "2" and then switch to a different tab using the mouse, and then press "2" again, the input won't be triggered so the tab won't switch.

I recently spoke with @jcheng5 and IIRC he agreed that supporting something like this could be useful. This is probably not a high priority but I wanted to make it an official request

@daattali
Copy link
Contributor Author

daattali commented Dec 2, 2015

Just out of curiousity, are there any plans on enabling this behaviour at some point, or is it more likely that inputs will always fire only when their value is changed? As I build more apps that use custom JavaScript and call Shiny.onInputChange() I run into this issue more and more often

@jcheng5
Copy link
Member

jcheng5 commented Dec 2, 2015

I'm hoping to tackle it not in this upcoming release but possibly the next. There are some open questions I have about how this should work. I think once those are decided this should be a very small change.

@daattali
Copy link
Contributor Author

daattali commented Dec 2, 2015

Thanks. As a potential user of this feature, I would like to be able to selectively choose when this would happen (I agree that by default the current system should be the one in place). Though I completely trust you and your design decisions so whatever you end up doing I'll be happy with. 👍

@philchalmers
Copy link

bump. @daattali suggested I point to another place where this came up. http://stackoverflow.com/questions/35831811/register-repeated-keyboard-presses-in-shiny. This was mainly to construct a toy psychometrics experiment with keyboard inputs, where repeated presses are very likely.

@byzheng
Copy link

byzheng commented Mar 7, 2016

+1 for this feature. Another situation to require this feature: I create a shiny app with DT and dashboard. The DT include a table with links to active other tabs and parse some values. Currently the shiny don't jump to another tab as the value doesn't change if I click the same link twice. I can provide a minimum example to reproduce my request if you like.

@pfgherardini
Copy link

+1 for this feature. My clunky workaround is to bundle in a JSON object the value I want to pass to the server together with a random number, so that the object is actually different which triggers the event.

@jpmarindiaz
Copy link

+1

3 similar comments
@Necklaces
Copy link

+1

@balazsdukai
Copy link

+1

@sorhawell
Copy link

+1

@calebbraun
Copy link

+1

@michaelspence
Copy link

+1

@daattali
Copy link
Contributor Author

@jcheng5 @wch
As one of the most +1'd issues , I'd like to nominate this issue to be tackled by your potential intern :)

@jpmarindiaz
Copy link

If it helps any one, this what I usually do to work around this issue. Adding an input binding that sends back to R a timestamp along with the data I want, so it changes every time a user interacts with the input.

Shiny.onInputChange('get_input', {id: event.id, timestamp:  new Date().getTime();})

@daattali
Copy link
Contributor Author

daattali commented Mar 13, 2018

Yup, that's essentially what I always use and what I've recommended others to do (although I choose to use a random number instead of current time - a combination of both would be better!)

But this is only a viable option if you yourself have control of both the javascript and the shiny server code. When I develop a package where I want to be able to return a value from javascript to the end-user, it's awkward to tell them in the documentation "Use input$foo$id to get the value" :)

@jcheng5
Copy link
Member

jcheng5 commented Apr 16, 2018

I'm seeing if I can sneak this into v1.1. Seems like this is mostly needed for Shiny.onInputChange purposes? Or do people want this for input bindings too?

@daattali
Copy link
Contributor Author

daattali commented Apr 16, 2018 via email

@dimmin
Copy link

dimmin commented Jul 1, 2021

It seems that this functionality is now available (since 3y) but still the initial example of daattali shows the same issue: could someone give an example on how one should managed it now? Thanks.

@ismirsehregal
Copy link
Contributor

There is an example linked above using priority: 'event':

#2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests