rcheckboxshiny

How to make R Shiny checkbox input work like a radio button?


When running the below R Shiny MWE code, the radio button works exactly as needed. You select only 1 item at a time with the other item automatically deselected, and the selected item printed to the console. Great!

But how can I make checkboxGroupInput() or checkboxInput() work in the exact same manner? I've been fiddling with this and can't get it to duplicate the behavior of radio button. For what it's worth, I post my last attempt at the bottom.

The reason I want this behavior is I have user selections stacked in the same column of a table. Most rows correctly use checkboxGroupInput() for multiple simultaneous item selections. Some selection items are for "one or the other", which is what radio buttons do well. But I would like to use the same format of user inputs throughout the column for clarity and sake of consistency, for the user's ease.

Here's the code with radio button, correct (desired) behavior:

library(shiny)

anchors <- c("Beginning", "Current")

ui <- fluidPage(
  radioButtons(
    inputId = 'anchor_select', 
    label = "", 
    choices = anchors,
    selected = NULL  
  )
)

server <- function(input, output) { 
  observeEvent(input$anchor_select, {
    print(input$anchor_select)
  })
}

shinyApp(ui = ui, server = server)

And here's my latest failed attempt to mimic radio button behavior using a checkbox instead. Problem is when I select "Current" it outputs "Current" twice, and to go from "Current" to "Beginning" I have to deselect "Current" and then select "Beginning". Deselection must be automatic.

ui <- fluidPage(
  checkboxGroupInput(
    inputId = 'anchor_select', 
    label = "", 
    choices = anchors,
    selected = "Beginning"
  )
)

server <- function(input, output, session) { 
  observeEvent(input$anchor_select, {
    if (length(input$anchor_select) > 1) {
      last_selected <- tail(input$anchor_select, 1)
      updateCheckboxGroupInput(session, "anchor_select", selected = last_selected)
      print(last_selected)
    } else if (length(input$anchor_select) == 1) {
      print(input$anchor_select)
    } else {
      updateCheckboxGroupInput(session, "anchor_select", selected = "Beginning")
      print("Beginning")
    }
  })
}

shinyApp(ui = ui, server = server)

Solution

  • I would suggest that you use shinyWidgets::prettyRadioButtons(), with icon set to icon("check"), and shape set to "square". That way you get functionality of radio button with styling of checkboxGroupInput

    anchors <- c("Beginning", "Current")
    
    ui <- fluidPage(
      shinyWidgets::prettyRadioButtons(
        inputId = "radio_anchor",
        label = "",
        choices = anchors,
        shape = "square",
        selected = "Beginning",
        icon = icon("check")
      )
    )