Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update conditional panels using action buttons

Tags:

r

shiny

I would like to be able to change conditional panels in R shiny using an actionButton. Reading through related questions I came up with the following example. That doesn't work! But I can't figure out why.

App code:

ui = fluidPage(

  conditionalPanel('output.CP_Flag == "1"', 'Condition met'),

  conditionalPanel('output.CP_Flag == "2"', 'Special case: Flag == 2'),

  conditionalPanel('output.CP_Flag != "1"', 'Condition not met'),

  selectInput(inputId = 'Selection',
              label = 'Select value, 1 meets the condition',
              choices = 1:10),

  actionButton(inputId = 'Change_Panel',
               label = 'Change Panel')

)
server = function(input, output, session) {

  CP_Flag = reactive({CP$Flag})
  output$CP_Flag = renderText({CP_Flag()})
  outputOptions(output, 'CP_Flag', suspendWhenHidden=FALSE)

  observeEvent(input$Change_Panel, Fn_CP_Function(as.numeric(input$Selection)))

}

shinyApp(ui, server)

Supporting code:

CP = new.env(parent = emptyenv())

CP$Flag = 2

Fn_CP_Function = function(i){
  CP$Flag = i
}

It's not an issue with format e.g. numeric vs. character, or with an inconsistent number of quotation marks because changing CP$Flag in R itself produces the result I would expect. It's just that the actionButton has no effect.

I'd be grateful for either (a) any insights into why this isn't working or (b) a code snippet that achieves the goal: updating conditional panels based on clicks of actionButtons.

like image 375
Jay Malone Avatar asked Jan 27 '26 12:01

Jay Malone


1 Answers

In the observeEvent, a new value is calculated, but it is not assigned to any reactive variables. You have to assign it to a reactiveVal() and make sure that the renderText called CP_Flag is dependent on that. Note that CP$Flag itself is not a reactive variable. Therefore, CP_Flag = reactive({CP$Flag}) will not change the CP_Flag reactive any time the function Fn_CP_Function is called.

So this should work:

CP = new.env(parent = emptyenv())
CP$Flag = 2
Fn_CP_Function = function(i){
  CP$Flag = i
}

ui = fluidPage(

  conditionalPanel('output.CP_Flag == "1"', 'Condition met'),

  conditionalPanel('output.CP_Flag == "2"', 'Special case: Flag == 2'),

  conditionalPanel('output.CP_Flag != "1"', 'Condition not met'),

  selectInput(inputId = 'Selection',
              label = 'Select value, 1 meets the condition',
              choices = 1:10),

  actionButton(inputId = 'Change_Panel',
               label = 'Change Panel')

)
server = function(input, output, session) {

  CP_Flag = reactiveVal(CP$Flag)
  output$CP_Flag = renderText({CP_Flag()})
  outputOptions(output, 'CP_Flag', suspendWhenHidden=FALSE)

  observeEvent(input$Change_Panel, CP_Flag(Fn_CP_Function(as.numeric(input$Selection))))

}

shinyApp(ui, server)

Also, you can do this with a bit less code. Your code might be part of a large program and you may have valid reasons to create a new environment and separate function, but I think it would be good to share this anyway since it may help your understanding:

ui = fluidPage(

  conditionalPanel('output.CP_Flag == "1"', 'Condition met'),
  conditionalPanel('output.CP_Flag == "2"', 'Special case: Flag == 2'),
  conditionalPanel('output.CP_Flag != "1"', 'Condition not met'),
  selectInput(inputId = 'Selection',
              label = 'Select value, 1 meets the condition',
              choices = 1:10),

  actionButton(inputId = 'Change_Panel',
               label = 'Change Panel')

)
server = function(input, output, session) {

  CP_Flag = reactiveVal(1)
  observeEvent(input$Change_Panel, CP_Flag(input$Selection))
  output$CP_Flag = renderText({CP_Flag()})
  outputOptions(output, 'CP_Flag', suspendWhenHidden=FALSE)
}

shinyApp(ui, server)
like image 117
Florian Avatar answered Jan 29 '26 06:01

Florian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!