Graham
Graham

Reputation: 176

R Shiny: Conditional actionButton within uiOutput

I have two actionButtons that allow navigation through numbers 1-6. However, I wish to remove the 'back' button only when the number 1 is displayed (but remain otherwise), and remove the 'next' button when on the number 6 (and remain throughout numbers 1-5), so as to provide a visual aid as to the start and end of the sequence.

Please see my unsuccessful code toward the bottom (#commented out as it prevents successful transitioning through numbers 2-5).

How could I conditionally render these buttons?

library(shiny)
library(shinyWidgets)



ui <- fluidPage(
  
  fluidRow(
    div(column(5,uiOutput("back"),align= "right")),
    div( column(5,uiOutput("next_q")),align = "left")),
  fluidRow(  
    column(5,offset = 3,id = "qa1", uiOutput("ui_q1"),br(),br(),
    )),
)

server <- function(input, output, session) {
  qbank=reactive(as.vector(c(1,2,3,4,5,6)))

  
  values <- reactiveValues()
  values$count <- 1
  myReactives <- reactiveValues(reactInd = 0)
  
  observe({
    input$next_q
    myReactives$reactInd <- 1
  })
  
  observe({
    input$back
    myReactives$reactInd <- 2
  })
  
  
  ntext <- eventReactive(input$next_q,{
    if(values$count != length(qbank())){
      values$count <- values$count + 1
      return(qbank()[values$count])
    }
    else{
      return(qbank()[length(qbank())])
    }
  })
  
  
  btext <- eventReactive(input$back,{
    if(values$count != 1){
      values$count <- values$count - 1
      return(qbank()[values$count])
    }
    else{
      return(qbank()[1])
    }
  })
  
  q <- reactive({
    if(input$next_q == 0){
      return(qbank()[1])
    }
    else if(myReactives$reactInd==1) return(
      ntext())
    else if(myReactives$reactInd==2)return(
      btext())
  })  
  
  q1 = reactive((q()[1]))
  output$q1 = renderText(q1())
  output$ui_q1 = renderUI(textOutput("q1"))
  
  
  output$back = renderUI({
    
    ## I cannot get the following if statement to function correctly
   # if(values$count==1) return (NULL)
   # else
      (actionButton("back","back"))})
  
  
  output$next_q = renderUI(    
    
    ## I cannot get the following if statement to function correctly
   # if(values$count==length(qbank()))
   # return (NULL)
   # else
      actionButton("next_q","next"))
}

shinyApp(ui, server)

Thank you

Upvotes: 0

Views: 1021

Answers (1)

user16051136
user16051136

Reputation:

I built a toy example that demonstrates how to remove the back button when at 1, and remove the next button when at 6. From this working example you may adapt your code to work a similar way:

library(shiny)

ui <- fluidPage(

    fluidRow(column(12,align="center",textOutput("currentNum"))),
    fluidRow(
        column(6,align="right",uiOutput("backBut")),
        column(6,align="left",uiOutput("nextBut"))
    )
    
)

server <- function(input, output) {
    
    rv <- reactiveValues(currPage=1)
    
    observeEvent(input$backButton,{
        rv$currPage <- rv$currPage - 1
    })
    
    observeEvent(input$nextButton,{
        rv$currPage <- rv$currPage + 1
    })
    
    output$currentNum <- renderText({rv$currPage})
    
    output$backBut <- renderUI({
        if(rv$currPage>1){
            actionButton("backButton","< Back")
        } 
    })
    
    output$nextBut <- renderUI({
        if(rv$currPage<6){
            actionButton("nextButton","Next >")
        } 
    })
   
}

shinyApp(ui = ui, server = server)

enter image description here

enter image description here

enter image description here

Upvotes: 3

Related Questions