widget request: bottons other than "submit" button

1,425 views
Skip to first unread message

Randall Pruim

unread,
Dec 6, 2012, 10:47:34 AM12/6/12
to shiny-...@googlegroups.com
I've created an app where I would like immediate response to sliders and other input widgets, but I would also like a button to "do it again" with the current settings.  My particular app involves randomization, so even with the same settings, the results will be different each time.

Is there currently a way to do this?  I couldn't find it in the tutorial.

Joe Cheng

unread,
Dec 6, 2012, 11:00:38 AM12/6/12
to shiny-...@googlegroups.com

Hi Randall, there is an actionButton in the shinyIncubator package that should do what you want:
https://github.com/RStudio/shiny-incubator

You can install with devtools::install_github("shiny-incubator", "rstudio")

On Dec 6, 2012 7:47 AM, "Randall Pruim" <rpr...@gmail.com> wrote:
I've created an app where I would like immediate response to sliders and other input widgets, but I would also like a button to "do it again" with the current settings.  My particular app involves randomization, so even with the same settings, the results will be different each time.

Is there currently a way to do this?  I couldn't find it in the tutorial.

--
 
 

Alex Yocom Piatt

unread,
Dec 6, 2012, 11:54:50 AM12/6/12
to shiny-...@googlegroups.com
Very nice.

I was just thinking about this issue as well.  Mostly understand is between this and Harlan's JS here:
https://groups.google.com/forum/?fromgroups=#!searchin/shiny-discuss/button/shiny-discuss/NQHvTCW2t2A/AhSUvmx21LwJ

Quick question: how do you connect this button event with a corresponding function in server.R?

Yann Richet

unread,
Dec 7, 2012, 3:15:49 AM12/7/12
to shiny-...@googlegroups.com
Hi,
you can just add a test in your server.R function so the number of clicks on the button are tested.
Then, just quit the function if #click==0

ui.R

shinyUI(pageWithSidebar( headerPanel("..."), sidebarPanel(
... actionButton('run','Run') ), mainPanel(...) ))

server.R

shinyServer(function(input, output) {
  output$results <- reactiveText(function() {
    if (as.numeric(input$run)==0) return(NULL);
...
}) })

Thomas Bristow

unread,
Dec 7, 2012, 4:47:21 PM12/7/12
to shiny-...@googlegroups.com
I have a selectInput and radiobutton list controlling a plot, so a user can browse data. An action button is available that I am hoping will eventually record the users data selections when pressed - one record for each push of the button.

Yann's code for the action button above works but continues to output "results" when selectInputs and radiobuttons are toggled after the action button is pressed. I want to find a way to set the actionButton counter back to a value of 0 or deactivate it again, after results are returned. Is this an instance when invalidateLater() can be used? If so, could you show me how.
Thanks.


Yann Richet

unread,
Dec 7, 2012, 5:01:27 PM12/7/12
to shiny-...@googlegroups.com
Maybe you also need a variable in shinyServer scope to keep the last status of the inputs, so you can precisely know what input was updated...

Thomas Bristow

unread,
Dec 7, 2012, 7:27:59 PM12/7/12
to shiny-...@googlegroups.com
I managed to fix my own problem (seems like it), using a global variable as a second counter and some logic. That way the action button will only fire the dependent function once per click - even if other reactive inputs to the function change.


UI_____________________

sidebarPanel(
    selectInput("...", "...", 
                choices = c()),
    
    uiOutput("radio"),
    
    actionButton("add", "add a mineral")
    ),

server______________________#partial example

output$caption <- reactiveText(function(){
  if (input$add==0) {
   count<<- 0
}
  count <<- count
  if (input$add==0 || count == input$add) 
    {
    return(NULL)}
   count<<- count+1
return (c(input$min,count))

Joe Cheng

unread,
Dec 7, 2012, 7:47:34 PM12/7/12
to shiny-...@googlegroups.com
The pain you're experiencing here is the impedance mismatch between the functional-reactive style that Shiny is designed for, and the imperative style ("on click, do this action") that most other GUI frameworks use (certainly most of the ones written before the last 18 months). I believe the functional-reactive style leads to much simpler and concise code, and far fewer errors for 90% of cases, but when you start wanting to do things that are by nature imperative (such as saving to the database) then it starts to get... interesting.

I have some ideas about how to allow you to move between one style and the other, but would like to spend a while longer watching what people are trying to do before implementing anything. In this case it seems like your problems could be solved by having a way to access reactive functions/values without actually taking a dependency on them (so that the code doesn't re-execute). Something like:

observe(function() {
  input$add  # take a dependency on the action button
  nonreactive({
    # Some logic
    saveToDatabase(input$foo, input$bar, input$baz)
    # Some more logic
  })
  # Or another way
  saveToDatabase2(nonreactive(input$foo))
})

So this observer would execute when input$add is clicked, but not when input$foo, $bar, and $baz change. "nonreactive" is a terrible name, but hopefully you get the idea.

Any thoughts?


--
 
 

Robert Bruggner

unread,
Dec 7, 2012, 8:08:33 PM12/7/12
to shiny-...@googlegroups.com
This is a functionality that I'm interested in well. Basically, I want to perform some specific operation when the actionbutton is clicked but not when any of the other reactive triggers fire. I like the action button widget in the shiny incubator package but there doesn't seem to be a specific way to tell if a reaction is triggered by that action button or another reactive input. 

However, now that you have emphasized the functional-reactive style of programming, I'm going to go back and see if I can change my interface style... Maybe that's  a better solution :)

Thomas Bristow

unread,
Dec 7, 2012, 8:24:08 PM12/7/12
to shiny-...@googlegroups.com
Thanks for the response Joe - that seems like a intuitive way to merge the two styles to me and I think it would work well for my particular application.

I am trying to construct an application where a user chooses data to be used in subsequent analysis in another tab -  either triggered by another button or navigation between tabs because of computational intensity. The action button will add elements to a list to be used in the calculation, but I am also going to try and have another action button on the same page to remove selected elements from the list.



On Friday, December 7, 2012 4:47:34 PM UTC-8, Joe Cheng [RStudio] wrote:

Yann Richet

unread,
Dec 10, 2012, 4:23:52 AM12/10/12
to shiny-...@googlegroups.com
I am not sure that it is fully related to this discussion thread, but another issue I often experiment is related to multiple input reactives : I want to let the reactive operate, only if two or more input are updated.
As far as I understand the current model, it is designed to update one output when _any_ of its input are updated.
For now, we can turn-around that using some "if ((input$...) == no.value) return(NULL)" at the beginning of the reactive function.

I wonder if a signature "update=function(input.new, input.old)" for the reactive function should allow to include an explicit control over reactive/nonreactive behavior...
(by default, this function is something like "any(input.new != input.last)")
Anyway, I have no idea if it is feasible :) And also it complicates a bit the current model which is fairly simple and efficient...

Joe Cheng [RStudio]

unread,
Dec 10, 2012, 2:44:48 PM12/10/12
to shiny-...@googlegroups.com
We don't have any solid ideas right now but more control over reactive calculations is something we're thinking about...

Ziyuan Lin

unread,
Dec 14, 2012, 1:04:00 AM12/14/12
to shiny-...@googlegroups.com
How to reset to counter of clicks to zero? I have an output dependent on a textInput. It will show only after a certain button is clicked. But if the button has been clicked, every time I change the content of the textInput, the output will change immediately. How to solve this?
Reply all
Reply to author
Forward
0 new messages