7

I am using R/shinydasboard to create a web app that I am putting behind a login screen.

I'm having trouble with getting the main body to render based on the sidebar menu tabs.

I've tried to ensure one of the tab items has selected = TRUE still to no avail.

Sample code below:

require(shiny)
require(shinydashboard)

Logged <- FALSE;
LoginPass <- 0; #0: not attempted, -1: failed, 1: passed

login <- box(title = "Login",textInput("userName", "Username (user)"),
             passwordInput("passwd", "Password (test)"),
             br(),actionButton("Login", "Log in"))

loginfail <- box(title = "Login",textInput("userName", "Username"),
                 passwordInput("passwd", "Password"),
                 p("Username or password incorrect"),
                 br(),actionButton("Login", "Log in"))

mainbody <- div(tabItems(
  tabItem(tabName = "t_item1", box(title = "Item 1 information")),
  tabItem(tabName = "t_item2", box(title = "Item 2 information")),
  tabItem(tabName = "t_item3", box(title = "Item 3 information"))
)
)

header <- dashboardHeader(title = "dashboard header")

sidebar <- dashboardSidebar(uiOutput("sidebarpanel"))

body <- dashboardBody(uiOutput("body"))

ui <- dashboardPage(header, sidebar, body)

server <- function(input, output, session) {
  USER <<- reactiveValues(Logged = Logged, LoginPass = LoginPass)
  observe({
    if (USER$Logged == FALSE) {
      if (!is.null(input$Login)) {
        if (input$Login > 0) {
          username <- isolate(input$userName)
          password <- isolate(input$passwd)
          #Id.username <- which(my_username == Username)
          if (username == "user" & password == "test") {
            USER$Logged <<- TRUE
            USER$LoginPass <<- 1
          }
          USER$LoginPass <<- -1
        }
      }
    }
  })

  output$sidebarpanel <- renderUI({
    if (USER$Logged == TRUE) {
      div(
        sidebarMenu(
          menuItem("Item 1", tabName = "t_item1", icon = icon("line-chart"), selected = TRUE),
          menuItem("Item 2", tabName = "t_item2", icon = icon("users")),
          menuItem("item 3", tabName = "t_item3", icon = icon("dollar"))
        )
      )}
  })
  output$body <- renderUI({
    if (USER$Logged == TRUE) {
      mainbody
    }
    else {
      if(USER$LoginPass >= 0) {
        login
      }
      else {
        loginfail
      }
    }
  })
}

shinyApp(ui, server)

Any suggestions on how to get the mainbody to show one of the tabs when it loads would be greatly appreciated. I have a suspicion it may due to the load order of the sidebar and the body however I am not sure how to investigate further.

I have also tried a conditionalPanel however couldn't get that to work either.

UPDATE This screenshot shows the behaviour that occurs straight after login. Current screen after login

This screenshot shows the desired behaviour after login.Desired screen after login

Dan
  • 2,625
  • 5
  • 27
  • 42
  • This does work for me, have you tried updating your packages and if you're using Rstudio doing the old classic shutdown and start? – RmIu Nov 20 '15 at 12:24
  • The code works, however it doesn't select the first menu item. Have updated the post with screenshots. – Dan Nov 23 '15 at 23:31
  • This is nice. I'm trying to 'read' the body from another R file with ``source(mybody.r``, but it doesn't work. Any ideas on this? If this is not clear I can provide an example. – Tim_Utrecht Nov 17 '16 at 15:48
  • @Tim_Utrecht try using `source(mybody.r, local = TRUE)` – Dan Dec 06 '16 at 20:24

1 Answers1

6

You need to set the tabItem as active:

tabItem(tabName = "t_item1", class = "active", box(title = "Item 1 information"))

It will render the first tab when you dynamically render the content after login.

Francois Vanderseypen
  • 1,432
  • 1
  • 12
  • 22
  • It's been a while coming Francois, this fell off my radar. I just tested it out, and works an absolute treat. – Dan Dec 06 '16 at 20:24