How to get new text input after entering a password in a tab?

42 views Asked by At

I'm trying to make a R shiny application where people need to answer a riddle (raadsel). When they get the correct answer a popup appears that they have the correct answer and in the main panel a sentence with congratulations, fill the password in the second tab: jouwwachtwoord. That password they have to enter in the second tab in order to get a new textinput where they have to fill their name in. The first part works, but when I go to the second tab and I fill in the password, nothing happens. Underneath I have my code, but I don't see where it goes wrong.

library(shiny)

# Definieer raadsels en antwoorden
raadsels <- c("Ik ben groot als ik jong ben, maar klein als ik oud ben. Wat ben ik?", 
              "Ik ben altijd om je heen, maar nooit gezien. Wat ben ik?")
antwoorden <- c("een boom", "lucht")

# UI voor de spiegel
ui <- fluidPage(
  titlePanel("Interactieve Spiegel"),
  tabsetPanel(
    tabPanel("Raadsel",
             sidebarLayout(
               sidebarPanel(
                 textInput("antwoord", "Wat is je antwoord?"),
                 actionButton("controleer", "Controleer Antwoord")
               ),
               mainPanel(
                 verbatimTextOutput("raadsel_output"),
                 verbatimTextOutput("feedback")
               )
             )
    ),
    tabPanel("Naam en Document",
             sidebarLayout(
               sidebarPanel(
                 conditionalPanel(
                   condition = "!input.wachtwoord_ingevuld",
                   passwordInput("wachtwoord", "Voer het wachtwoord in:"),
                   actionButton("ontgrendel", "Ontgrendel")
                 ),
                 conditionalPanel(
                   condition = "input.wachtwoord_ingevuld",
                   textInput("naam", "Vul je naam in:"),
                   actionButton("bevestig_naam", "Bevestig Naam"),
                   downloadButton("download_doc", "Open Document")
                 )
               ),
               mainPanel(
                 verbatimTextOutput("document_output")
               )
             )
    )
  )
)

# Server logica
server <- function(input, output, session) {
  
  wachtwoord_ingevuld <- reactiveVal(FALSE)
  correct_antwoord_gegeven <- reactiveVal(FALSE)
  
  output$raadsel_output <- renderText({
    raadsels[1]  # Weergeef het eerste raadsel
  })
  
  output$feedback <- renderText({
    if (correct_antwoord_gegeven()) {
      "Gefeliciteerd! Voer het wachtwoord in om verder te gaan."
    } else {
      ""
    }
  })
  
  observeEvent(input$controleer, {
    antwoord <- tolower(input$antwoord)  # Antwoorden zijn niet hoofdlettergevoelig
    
    if (antwoord %in% tolower(antwoorden)) {
      showModal(
        modalDialog(
          title = "Goed Geraden!",
          "Jullie mogen de envelop openen."
        )
      )
      correct_antwoord_gegeven(TRUE)
    } else {
      showModal(
        modalDialog(
          title = "Fout Antwoord",
          "Het antwoord is niet correct. Probeer het opnieuw."
        )
      )
    }
  })
  
  observe({
    if (correct_antwoord_gegeven() && input$wachtwoord == "jouwwachtwoord") {
      wachtwoord_ingevuld(TRUE)
    }
  })
  
  observeEvent(input$bevestig_naam, {
    if (input$naam != "") {
      showModal(
        modalDialog(
          title = "Gefeliciteerd!",
          paste("Bedankt,", input$naam, "! Klik op 'Open Document' om uw document te downloaden.")
        )
      )
    } else {
      showModal(
        modalDialog(
          title = "Fout",
          "Voer alstublieft uw naam in."
        )
      )
    }
  })
  
  output$document_output <- renderText({
    if (wachtwoord_ingevuld() || correct_antwoord_gegeven()) {
      paste("Dit is het document voor", input$naam)
    } else {
      ""
    }
  })
}

# Run de app
shinyApp(ui = ui, server = server)

1

There are 1 answers

0
Jan On

For the conditionalPanel, you are using a condition which relies on input.wachtwoord_ingevuld. However, wachtwoord_ingevuld is an output value which you calculate on the server side, not an input value.

Hence you have to rewrite your code using output.wachtwoord_ingevuld, see the example below which works.

library(shiny)

# Definieer raadsels en antwoorden
raadsels <- c("Ik ben groot als ik jong ben, maar klein als ik oud ben. Wat ben ik?", 
              "Ik ben altijd om je heen, maar nooit gezien. Wat ben ik?")
antwoorden <- c("een boom", "lucht")

# UI voor de spiegel
ui <- fluidPage(
  titlePanel("Interactieve Spiegel"),
  tabsetPanel(
    tabPanel("Raadsel",
             sidebarLayout(
               sidebarPanel(
                 textInput("antwoord", "Wat is je antwoord?"),
                 actionButton("controleer", "Controleer Antwoord")
               ),
               mainPanel(
                 verbatimTextOutput("raadsel_output"),
                 verbatimTextOutput("feedback")
               )
             )
    ),
    tabPanel("Naam en Document",
             sidebarLayout(
               sidebarPanel(
                 conditionalPanel(
                   condition = "!output.wachtwoord_ingevuld",
                   passwordInput("wachtwoord", "Voer het wachtwoord in:"),
                   actionButton("ontgrendel", "Ontgrendel")
                 ),
                 conditionalPanel(
                   condition = "output.wachtwoord_ingevuld",
                   textInput("naam", "Vul je naam in:"),
                   actionButton("bevestig_naam", "Bevestig Naam"),
                   downloadButton("download_doc", "Open Document")
                 )
               ),
               mainPanel(
                 verbatimTextOutput("document_output_text")
               )
             )
    )
  )
)

# Server logica
server <- function(input, output, session) {
  
  #wachtwoord_ingevuld <- reactiveVal(FALSE)
  correct_antwoord_gegeven <- reactiveVal(FALSE)
  
  output$raadsel_output <- renderText({
    raadsels[1]  # Weergeef het eerste raadsel
  })
  
  output$feedback <- renderText({
    if (correct_antwoord_gegeven()) {
      "Gefeliciteerd! Voer het wachtwoord in om verder te gaan."
    } else {
      ""
    }
  })
  
  observeEvent(input$controleer, {
    antwoord <- tolower(input$antwoord)  # Antwoorden zijn niet hoofdlettergevoelig
    
    if (antwoord %in% tolower(antwoorden)) {
      showModal(
        modalDialog(
          title = "Goed Geraden!",
          "Jullie mogen de envelop openen."
        )
      )
      correct_antwoord_gegeven(TRUE)
    } else {
      showModal(
        modalDialog(
          title = "Fout Antwoord",
          "Het antwoord is niet correct. Probeer het opnieuw."
        )
      )
    }
  })
  
  output$wachtwoord_ingevuld <- reactive({
    if (correct_antwoord_gegeven() && input$wachtwoord == "jouwwachtwoord") {
      TRUE
    } else {
      FALSE
    }
  })
  
  observeEvent(input$bevestig_naam, {
    if (input$naam != "") {
      showModal(
        modalDialog(
          title = "Gefeliciteerd!",
          paste("Bedankt,", input$naam, "! Klik op 'Open Document' om uw document te downloaden.")
        )
      )
    } else {
      showModal(
        modalDialog(
          title = "Fout",
          "Voer alstublieft uw naam in."
        )
      )
    }
  })
  
  document_output <- reactive({
    if (correct_antwoord_gegeven() || input$wachtwoord == "jouwwachtwoord") {
      paste("Dit is het document voor", input$naam)
    } else {
      ""
    }
  })
  
  output$document_output_text <- renderText({
    print(document_output())
  })
  
  outputOptions(output, "wachtwoord_ingevuld", suspendWhenHidden = FALSE)
}

# Run de app
shinyApp(ui = ui, server = server)