Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Shiny: How to hide tabPanel by a condition in server

Tags:

r

shiny

tabpanel

I modified an answer given in here to write a very simple login/logout system using the Shiny package in R. I would like to hide panel "B" if USER$Logged is FALSE (i.e. user is logged out) and show it whenever USER$Logged is TRUE (i.e. user is logged in). In other words, once you run the code, it should not show panel B, until the user correctly enter username and password. I tried to use conditionalPanel but it does not hide panel B. It is currently showing it all the time regardless of USER$Logged. Does anyone know how to fix it?

library(shiny)
library(shinydashboard)
my_username <- "test"
my_password <- "abc"
shinyApp(
  shinyUI(
    navbarPage( tabPanel("A", uiOutput('loginpage')),
               tabPanel("B", uiOutput('page1'),conditionalPanel(condition = "output.cond1==TRUE"))
                            )
                            ),
  shinyServer(function(input, output, session) {
    USER <<- reactiveValues(Logged = FALSE)
    observe({
      if (USER$Logged == FALSE) {
        output$loginpage <- renderUI({
          box(title = "",textInput("userName", "Username"),
              passwordInput("passwd", "Password"),
              br(),
              actionButton("Login", "Log in"))})
      } else if (USER$Logged == TRUE) {
        output$loginpage <- renderUI({fluidPage(
          box(title = "",br(),br(),actionButton("logout", "Logout"))
        )

        })
      }
    })

    observeEvent(input$Login, {
      if (!is.null(input$Login)) {
        if (input$Login > 0) {
          Username <- isolate(input$userName)
          Password <- isolate(input$passwd)
          Id.username <- which(my_username == Username)
          Id.password <- which(my_password == Password)
          if (length(Id.username) > 0 & length(Id.password) > 0) {
            if (Id.username == Id.password) {
              USER$Logged <<- TRUE

            } 
          }
        } 
      }

    })

    observeEvent(input$logout, {
      USER$Logged <<- FALSE
    })

    output$cond1 = reactive({
      USER$Logged==TRUE
    })

                       }     ))
like image 512
R User Scientist Avatar asked Oct 17 '22 19:10

R User Scientist


1 Answers

You could use the shinyjs package to show/hide the tab. To do this, I added an id to the navbar so that we can select the tab to show/hide. The you can add a shinyjs::show/hide in your observe to show or hide the tab when the user is logged in or out. One last note is you need to call useShinyjs() somewhere in your UI so the functions will work. I also made some minor edits to your code (e.g. getting rid of <<-. The app is:

library(shinyjs)
shinyApp(
  shinyUI(
    navbarPage( id = "navbar",
                useShinyjs(),
                tabPanel("A", uiOutput('loginpage')),
                tabPanel("B", uiOutput('page1'),conditionalPanel(condition = "output.cond1==TRUE"))
    )
  ),
  shinyServer(function(input, output, session) {
    USER <- reactiveValues(Logged = FALSE)

    observe({
      if (USER$Logged == FALSE) {
        output$loginpage <- renderUI({
          box(title = "",textInput("userName", "Username"),
              passwordInput("passwd", "Password"),
              br(),
              actionButton("Login", "Log in"))})

        shinyjs::hide(selector = "#navbar li a[data-value=B]")

      } else if (USER$Logged == TRUE) {
        output$loginpage <- renderUI({fluidPage(
          box(title = "",br(),br(),actionButton("logout", "Logout"))
        )})

        shinyjs::show(selector = "#navbar li a[data-value=B]")
        }

    })

    observeEvent(input$Login, {
          Id.username <- which(my_username == input$userName)
          Id.password <- which(my_password == input$passwd)
          if(Id.username & Id.password) USER$Logged <<- TRUE
    })

    observeEvent(input$logout, {
      USER$Logged <- FALSE
    })
    }))
like image 60
Mike H. Avatar answered Nov 15 '22 08:11

Mike H.