updateActionButton

453 views
Skip to first unread message

Norman Packard

unread,
May 13, 2015, 6:20:22 PM5/13/15
to shiny-...@googlegroups.com
I know this is a long-standing issue, and I know that Joe Cheng always maintains that desires for updateActionButton are misguided, in that that there is a proper way to achieve desired functionality without it.

However, I don't find the following functionality discussed explicitly so far, so I'll try it out.  It has to do with using a conditional panel that looks at an action button value for its condition (this is in ui.R, *not* server.R).

In a sidePanel I have something like:

sidePanel(...
actionButton(doit,"Configure this variable")
...
)

then in a main panel I have something like

mainPanel(   ...
   # for action button not pushed:
   conditionalPanel(condition="input.doit == 0 & input.tabs==...",
                                ...),
   ...
   # for action button pushed:
   conditionalPanel(condition="input.doit > 0 & input.tabs==...",
                                ...),

Now, at some later point (maybe triggered by another action button), I would like to reset input.doit and re-display the first conditional panel, have the user re-specify inputs there, etc.  Seems like it would be quite natural to have something like updateActionButton() over in server.R to get me back to my first conditional panel. 

I would be very happy to hear the 'right and proper' way to do this, given that  updateActionButton() does not exist.  Very sorry if I have missed the solution in previous discussions.

Andrew Yip

unread,
May 14, 2015, 5:25:46 AM5/14/15
to shiny-...@googlegroups.com
Hi Norm, I'm not exactly on the updateActionButton issue, but wonder if you could shed some light on using actionLink/actionButton inside a render-element in server.R. Since it is not under ui.R, no input$foo is created for my actionLink("foo", ...) in a render-element in server.R. Thoughts?

Norman Packard

unread,
May 14, 2015, 3:51:21 PM5/14/15
to shiny-...@googlegroups.com

Hi Andrew,

I'm not sure I see your problem in my code.  When I use renderUI() in server.R, I create an input element like:

    output$choose_sheet = renderUI({
        selectInput('sheet','Sheet',as.list(sheetnames))
    })

Then later (elsewhere in server.R), I access the results of that selectInput render-element with input$sheet.  So sheet has been added to input, even though it was created inside renderUI instead of in ui.R.

Admittedly, I haven't tried this with an actionButton.


Andrew Yip

unread,
May 14, 2015, 4:53:03 PM5/14/15
to shiny-...@googlegroups.com
sorry for not being clear. am actually asking a separate question wondering if you have some thoughts on it since you are also working with actionLink.

Joe Cheng

unread,
May 18, 2015, 3:17:38 PM5/18/15
to Andrew Yip, shiny-...@googlegroups.com
Andrew, not sure why your actionLink isn't working inside a uiOutput/renderUI, it certainly should.

Norman, that's a good one :) Most of the other instances have purely involved juggling state on the server, the conditionalPanel means we have to communicate the state back to the client.

I might be thawing a bit on updateActionButton but in the meantime here's how you would do it without it:

mainPanel(   ...
   # for action button not pushed:
   conditionalPanel(condition="!output.hideinputs && input.tabs==...",
                                ...),
   ...
   # for action button pushed:
   conditionalPanel(condition="output.hideinputs && input.tabs==...",
                                ...),

(By the way, I noticed you used single & for boolean-AND, that's not correct for JavaScript--you need &&.)

Then on the server:

function(input, output, session) {
  # These two lines are a way to create a single reactive value variable
  hideinputs <- FALSE
  makeReactiveBinding("hideinputs")

  observeEvent(input$doit, {
    hideinputs <- TRUE
  })
  observeEvent(input$reset, { # or whatever
    hideinputs <- FALSE
  })

  # These two lines take the value of hideinputs and make it available
  # in the client as output.hideinputs. It's a little verbose, we should
  # probably have a convenience function for this.
  output$hideinputs <- reactive(hideinputs)
  outputOptions(output, "hideinputs", suspendWhenHidden = FALSE)
}

This would have a disadvantage versus updateActionButton in that the controls wouldn't hide until the output is ready (since the value of output.hideinputs isn't updated until all the other outputs are ready to update as well).


--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/48507745-b18f-4843-9a2a-cc047bc28655%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Norman Packard

unread,
May 18, 2015, 8:01:36 PM5/18/15
to shiny-...@googlegroups.com, yip...@gmail.com
Joe,

Thanks, as always.  Very clear.  I didn't realize you could create an output with makeReactiveBinding and then refer to it in the condition.  This is quite useful, more generally than the actionButton reset surrogate.

Thanks again,
  N

Dean Attali

unread,
Jun 26, 2015, 8:35:20 PM6/26/15
to shiny-...@googlegroups.com, yip...@gmail.com
Hi Joe

I've used a similar approach to what you mentioned many times before but I've used a different syntax.
Instead of creating a reactive binding, this is all I did in the server:

output$reset <- reactive({ FALSE })
outputOptions(output, 'reset', suspendWhenHidden = FALSE)

I've done this in many apps and it always worked perfectly without a problem. Should I change my code to what you suggested? If so, can you explain the advantage of your method?

Dean Attali

unread,
Jun 26, 2015, 8:39:20 PM6/26/15
to shiny-...@googlegroups.com, yip...@gmail.com
I should have put a bit more time and thought into this, now I think I see the difference. I think that by using `makeReactiveBinding` it makes the variable work as part of the reactive system, whereas without that it would still be a "reactive" variable in the sense that it could be assigned reactive values, but you wouldn't be able to "observe" on it. Let me know if that's wrong 

Joe Cheng

unread,
Jun 28, 2015, 5:44:36 PM6/28/15
to Dean Attali, shiny-...@googlegroups.com, yip...@gmail.com
Right, if you want to actually read that value on the server side then I would use my approach. And also I just tend to want to define outputs once, if possible--for me it's easier to reason about and debug.
--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages