0
votes

Sorry if this is a common question, but it's driving me nuts. I need to add an actionButton to a Shiny UI that triggers a file save. The actual file save command depends upon which tab of a tabPanel is open, and I can get that information via the tabPanel id. The problem I'm having is with accessing the state of the actionButton and resetting it afterwards.

In ui.r, I have something like this:

shinyUI(fluidPage(
    titlePanel("myTitle"),

    sidebarLayout(
        sidebarPanel("",
            actionButton("save", "Save File"),

            # test to make sure the button is working
            verbatimTextOutput("sb")    # it increments when clicked
        )
    )
))

In server.r, I'm trying to do this:

shinyServer(function(input, output) {

    # test to make sure the button is working
    output$sb <- renderPrint({ input$save })     # increments when clicked

    # here is the problem code:
    if(input$save > 0) {                         # button was clicked, so...
        input$save <- 0                          # reset the flag
        print("HERE")                            # and do something else
    }
})

Of course, I'll check the status of the tabPanel instead of printing "HERE", which will likely generate another question if I get past this problem. How do I access and change the value of input$save in the server.r code? There is no evidence that the code inside the if() conditional statement is being executed, so I assume that the logical test is either not being performed, or is returning FALSE even though the value of input$save increments whenever the button is clicked.

Thanks for any advice. As is probably apparent, I'm very new to Shiny and am finding it rather opaque, so far.

Best, --Mike C.

2

2 Answers

5
votes

If your code needs to reexecute whenever an input changes, it can't just be inside your server function like you have the if right now. You need to put that inside an observe block:

observe({
  if (input$save == 0)
    return()

  isolate({
    # Do your saving in here
  })
})

You absolutely don't need to reset the value of input$save to 0. I believe that so wholeheartedly that I specifically left that ability out of the framework. The actual value of input$save is meaningless EXCEPT for the value 0 which simply means "the button has NEVER been clicked"; for every other value, the value itself is not important, just that it changed. Every time you get to the # Do your saving in here line, it means the user clicked the Save button. It shouldn't matter to you whether it is the 1st or 100th time it was clicked; the fact is that the user just clicked it and you should now save.

1
votes

I'm guessing that code is only getting run once when you start the shinyServer. I think you need to be inside a reactive block in order to run on model changes. Otherwise that block of code as it stands now will never get re-evaluated.