10

The goal is to have a shiny module ui1.R that loads a second module ui2.R when the button confirm is clicked. I think the issue is that is.null(input$confirm) is always invalidated. What I need instead, is to invalidate the expression only once confirm is clicked. The question is very close to Starting Shiny app after password input, but I am trying to modularize the solution.

ui.R

library(shiny)
library(shinyjs)
htmlOutput("page")

server.R

rm(list = ls())
library(shiny)
library(dplyr)
library(shinyjs)
Logged <-  FALSE

shinyServer(function(input, output) {

  source('ui1.R') #login page
  source('ui2.R')


  observeEvent(!is.null(input$confirm), {
    Logged <<- T
  })

  observe({
    if (Logged == FALSE) {
      output$page <- renderUI({ 
        ui1Output('ui1Output') 
      })
      output$lsuId <- renderText({ input$lsuId })
    }
    if (Logged == TRUE) 
    {
      output$page <- renderUI({ ui2 })
    }
  })
  callModule(ui1,'ui1') 
})

ui1.R

library(shinyjs)

ui1Output <-  function(id, label = "ui1") {
  ns <- NS(id)
  shinyUI(fluidPage(
    useShinyjs(),
    titlePanel("Form"),
    div(textInput(ns("lsuId"), "This has to be filled", ""),
      actionButton(ns("confirm"), "Submit", class = "btn-primary")
    )
  ))
}

ui1 <- function(input, output, session) {
  observe({
    LSUID <- reactive({ input$lsuId })
    shinyjs::toggleState(id = "confirm", condition = LSUID())
  })
}

ui2.R

ui2<-  shinyUI(fluidPage(
 div("well done!")
))

global.R

source('ui1.R') #login page
source('ui2.R')
2

2 Answers 2

2

I think you have two issues here:

First your confirm button value is stored here: input$"ui1Output-confirm" and not here: input$confirm

I would suggest to replace:

observeEvent(is.null(input$confirm), {
  Logged <<- F
})

By:

observeEvent(input$"ui1Output-confirm", {
    Logged <<- T
})

Then your observe function does not contain any reference to the button so it is not executed when the user clicks on it. I don't have a proper solution for this but a simple hack would be to add:

tmp <- input$"ui1Output-confirm"

at the begining of the observe section:

observe({
    tmp <- input$"ui1Output-confirm"

    if (Logged == FALSE) {
        output$page <- renderUI({ 
            ui1Output('ui1Output') 
        })
        output$lsuId <- renderText({ input$lsuId })
    }
    if (Logged == TRUE) 
    {
         output$page <- renderUI({ ui2 })
    }
})
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. Would you articulate why once I fixed the reference to the button using ui1Ouput-confirm it still does not work? Also, I don't understand the role of your last line of code. I thought once observeEvent is invalidate, what is inside would be executed...and if it does, and Logged becomes TRUE then the page should switch to the second one (i.e., logging-in).
Your observeEvent was putting Login to False so I did not understand what you wanted to achieve, it is why I changed it. For the observe element, it does not detect the Logged change, I have some ideas why but I am really not sure so it would be better if someone with more knowledge answers this question.
Ok I fixed the code in the original question. What I didn't understand was the reason why you added an additional if, since I thought the conditional statement was embedded in observeEvent already. I'm still not sure how to use tmp<- input$A"ui1Output-confirm.
You are right my if statement is useless, I edited my first post. I also show you were I used the tmp variable. You need to use this trick because, Logged is a standard variable so shiny does not monitor its value.
Thanks, also you don't need to assign input$"ui1Output-confirm" to an object.
1

Here is my solution. It is not perfect but it is simple.

library(shiny)

ui <- fluidPage(
        conditionalPanel(
          condition = "input.password != 'password'",  
          textInput("password", "Password:", value = "Type the password here")
        ), 
        conditionalPanel(
          condition = "input.password == 'password'",  
          fluidRow(
               column(2,
                 textInput("Green", "Green:", value = "24716"), 
                 textInput("Blue", "Blue:", value = "24700")
               )
          )
        ),  
        plotOutput(outputId = "distPlot")
)

server <- function(input, output, session) {
  output$distPlot <- renderPlot({
    if (input$password!="password") return(0)
    plot(c(1,2,3),c(1,2,3))
  })
}

app=shinyApp(ui, server)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.