Programatically Fire A Button Click Event

2,408 views
Skip to first unread message

Dario Strbenac

unread,
Jul 27, 2015, 2:00:19 AM7/27/15
to Shiny - Web Framework for R
Does Shiny have the capability to fire an event programatically ? Imagine there is a table and a button to click on, which determines which row the maximum value occurs in, considering only the user-selected rows. Also, there is another button to deselect all rows of the table. When the button to deselect all rows is clicked, I would like to fire the click event of the button to determine the maximum value's row, so that it processes and updates the text displayed under the table to show that no rows are currently selected and calculating the maximum is not possible.

For example,

output[["maxText"]] <- renderText({
    input[["maxCalcButton"]]
    isolate({  # Only recalculate when maxCalcButton is clicked.
      if(length(input[["aTable_rows_selected"]]) == 0)
        "No rows are selected."
      else
        "Row with maximum value: 7." # To shorten the example.
    })
})

observeEvent(input[["deselectButton"]], {
  selectRows(tableProxy, NULL)
  # Something like: fireEvent(
input[["maxCalcButton"]])
})

Amber James

unread,
Jul 27, 2015, 2:28:22 AM7/27/15
to Shiny - Web Framework for R, dario....@gmail.com
Why dont you just use 2 observe events? You could then remove your isolate. 
observeEvent( c(input$maxCalcButton, input$deselectButton), {
    output$maxText
<- renderText({
    input
$maxCalcButton
   
# Only recalculate when maxCalcButton is clicked.
     
if(length(input$aTable_rows_selected) == 0)

       
"No rows are selected."
     
else
       
"Row with maximum value: 7." # To shorten the example.
   
})
})


observeEvent
(input$deselectButton, {
  selectRows
(tableProxy, NULL)
 
# Something like: fireEvent(input$maxCalcButton)
})

This code would force the maxText element to only be updated if the deselect button or if the max calc button is fired. 

Dario Strbenac

unread,
Jul 27, 2015, 4:00:07 AM7/27/15
to Shiny - Web Framework for R, amber....@gmail.com
Removing the isolation would cause the event to be triggered whenever a user clicks on a row, because the function makes reference to aTable_rows_selected. It should only be triggered when the maxButton button is clicked. With isolation retained, clicking the deselection button does nothing for the first time. It only fires the event if the button is clicked twice. Below is an example you can run easily. Is it a Shiny bug that I have discovered ? I wonder why the event isn't handled with just one click.

library(shiny)
library(DT)
shinyApp(
  ui = fluidPage(
    fluidRow(
      dataTableOutput("aTable")
    ),
    fluidRow(
      actionButton("maxButton", "Find Maximum"), actionButton("deselectButton", "Deselect All")
    ),
    fluidRow(textOutput("maxText"))
  ),
  server = function(input, output, session) {
    output[["aTable"]] = renderDataTable({datatable(iris, options = list(dom = 't'))})
    tableProxy <- dataTableProxy("aTable")

    observeEvent(c(input[["maxButton"]], input[["deselectButton"]]),
    {
      output[["maxText"]] <- renderText({
      isolate({
         selectedRows <- input[["aTable_rows_selected"]]
         if(length(selectedRows) > 0)
           selectedRows[which.max(iris[selectedRows, 1])]
         else "Nothing."
      })

    })
    })

    observeEvent(input[["deselectButton"]],
               {
                 selectRows(tableProxy, NULL)
               })
})

Bryce Chamberlain

unread,
Jan 8, 2018, 11:25:13 PM1/8/18
to Shiny - Web Framework for R
I found a solution to a similar problem. updateActionButton doesn't actually change the value of the button, I think - only the label. So it doesn't cause reactive updates. Instead I created a hidden numericInput and changed the value of that, and made reactives react to the hidden input. Basically treating it like a button.

something like:

# in the UI, using shinyjs
hidden( numericInput( inputId = 'refresh_helper', value = 0 ) )

# my observer:
observeEvent
( input$refresh_helper, {} )
# or in a reactive use:
t
= input$refresh_helper

# then in your code where you want to refresh, use:

updateNumericInput( session = session, inputId = 'refresh_helper', value = input$refresh_helper + 1 )

I threw that together with no testing (no time!), it probably isn't perfect. If you get some working code, please post it if you like.

Hopefully that helps!
Reply all
Reply to author
Forward
0 new messages