user4065758
user4065758

Reputation: 319

Update label of actionButton in shiny

I know that similar question was already answered, however the solution creates a new actionButton with different label upon string-input. What I need is to keep the button(the counter of the button), because when I change the label and create a new button it has a counter of 0(not clicked).

So basically I need something like an update function to just change the label of the actionButton, when it is pressed. You press it once and the label changes.

input$Button <- renderUI({
    if(input$Button >= 1) label <- "new label"
    else label <- "old label"
    actionButton("Button", label = label)
})

Something like this, but without reseting the value of the button(by creating a whole new one).

Thanks!

Upvotes: 5

Views: 4473

Answers (3)

Rumpl
Rumpl

Reputation: 343

A few years later some small addition: If you want to switch between button icons, e.g. play / pause button (and switching between labels would be similar) you could do something like this (based on shosaco's answer).

library(shiny)

ui <- fluidPage(
  fluidRow(
    actionButton("PlayPause", NULL, icon = icon("play"))
    )
)

server <- function(input, output, session) {
  # whenever the ActionButton is clicked, 1 is added to input$PlayPause
  # check if input$PlayPause is even or odd with modulo 2 
  # (returns the remainder of division by 2)
  observeEvent(input$PlayPause, {
    if (input$PlayPause %% 2 != 0) {
      updateActionButton(session, "PlayPause", NULL, icon = icon("pause"))
    } else {
      updateActionButton(session, "PlayPause", NULL, icon = icon("play"))
    }
  })
}

shinyApp(ui = ui, server = server)

Upvotes: 1

shosaco
shosaco

Reputation: 6165

You can use updateActionButton from native shiny package:

ui <- fluidPage(
  actionButton('someButton', ""),
  h3("Button value:"),
  verbatimTextOutput("buttonValue"),
  textInput("newLabel", "new Button Label:", value = "some label")
)

server <- function(input, output, session) {

  output$buttonValue <- renderPrint({
    input$someButton
  })

  observeEvent(input$newLabel, {
    updateActionButton(session, "someButton", label = input$newLabel)
  })
}

shinyApp(ui, server)

enter image description here

Upvotes: 4

Tonio Liebrand
Tonio Liebrand

Reputation: 17689

  1. reactiveValues() can help. Check http://shiny.rstudio.com/articles/reactivity-overview.html for details. In the following example, I renamed your input$Button to input$click to avoid double usage of the "Button" name. Since we wrap the label in a renderUI(), input$click initially fires once it is created?!?, that's why I put the label condition as: if(vars$counter >= 2)

  2. An alternative solution could be to remove the read-only attribute (found here: https://github.com/rstudio/shiny/issues/167)

    attr(input, "readonly") <- FALSE
    input$click <- 1
    
  3. For an example paste the following in your R console:

    ui <- bootstrapPage(
        uiOutput('Button')
    )
    
    server <- function(input, output) {
    
        # store the counter outside your input/button
        vars = reactiveValues(counter = 0)
    
        output$Button <- renderUI({
            actionButton("click", label = label())
        })
    
        # increase the counter
        observe({
            if(!is.null(input$click)){
                input$click
                isolate({
                    vars$counter <- vars$counter + 1
                })
            }
        })
    
        label <- reactive({
            if(!is.null(input$click)){
                if(vars$counter >= 2) label <- "new label"
                else label <- "old label"
            }
        })
    }
    
    # run the app
    shinyApp(ui = ui, server = server)
    

Upvotes: 4

Related Questions