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')
Community
  • 1
  • 1
Dambo
  • 3,318
  • 5
  • 30
  • 79

2 Answers2

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 })
    }
})
user1470500
  • 652
  • 5
  • 14
  • 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). – Dambo Jul 25 '16 at 04:51
  • 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. – user1470500 Jul 25 '16 at 05:27
  • 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`. – Dambo Jul 25 '16 at 05:36
  • 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. – user1470500 Jul 25 '16 at 07:43
  • Thanks, also you don't need to assign `input$"ui1Output-confirm"` to an object. – Dambo Jul 25 '16 at 14:50
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)
kimman
  • 371
  • 2
  • 4