Search code examples
htmlcssrshinycarousel

How to isolate conditional panels from other conditional panels?


I'm having trouble with the formats of conditional panels affecting other conditional panels. Below is reproducible code, and at the bottom are images better explaining the issue. In the fuller App this code derives from, the problem is more obvious and makes it look sloppy (in the fuller App, there are multiple screens the user clicks through as the user scrolls to the right along the shaded bar (Well Panel) at the top just underneath the tab label, and the misalignment gets more pronounced as the user scrolls to the right).

The problem is: as the user scrolls right through the Glide Controls / Well Panels to make selections, the Well Panels (at the top with radio buttons) begin to misalign with the table and/or plots that appear beneath. The misalignment gets more pronounced as the user scrolls right. This misalignment isn't as apparent in this reproducible example, but is more pronounced in the fuller App this derives from where there are multiple "screens" or Well Panels at the top for the user to scroll through and where there are data tables and/or plots presented underneath in the main panel.

For sake of simplicity all server code is eliminated in this example (no plots, no tables), as the issue still presents without the server code.

If I comment-out other conditional panels (marked "###" in the reproducible code) the misalignment goes away. So how can I make the conditional panels independent of one another, as a way of eliminating this misalignment? I'm open to any other suggestions for eliminating this misalignment.

The basic structure of the App is the user makes "big choices" along the sidebar panel, and makes more "refined choices" only the top bar underneath the tab label using Glide Controls/Well Panels etc. for a carousel affect.

Reproducible code:

library(shiny)
library(shinyglide)
library(shinyjs)
library(shinyWidgets)

ui <- 
  fluidPage(
    useShinyjs(),
    tags$style(".glide-controls { position: absolute; top: 8px; right: 14px; width: 160px; }"), 
    titlePanel("Hello"),
    sidebarLayout(
      sidebarPanel(selectInput("selectData", h5(strong("Select data to view:")),choices = list("Stratification","DnL balances"),selected = "Stratification")),
      mainPanel(
        tabsetPanel(
          tabPanel("Private data", value = 1,
                   div(style = "margin-top:10px"),
                   conditionalPanel(condition = "input.selectData == 'Stratification'",
                     fluidRow(
                       column(12,
                         glide(
                           custom_controls = div(class = "glide-controls", glideControls()), 
                           screen(
                             wellPanel(
                                radioButtons(
                                  inputId = 'groupStrats',
                                  label = NULL,
                                  choiceNames = c('Calendar period','MOB'),
                                  choiceValues = c('Period','MOB'),
                                  selected = 'Period',
                                  inline = TRUE), 
                                style = "padding-top: 12px; padding-bottom: 0px;") 
                           ), 
                           screen(
                             wellPanel(
                                radioButtons(
                                  inputId = 'stratsView',
                                  label = NULL,
                                  choices = list("Table view" = 1,"Plot view" = 2),
                                  selected = 1,
                                  inline = TRUE), 
                                style = "padding-top: 12px; padding-bottom: 0px;") 
                           ) 
                        ) 
                     ) 
                   ),
                   ### Deleting next line resolves the well panel issue ###
                   conditionalPanel(condition = "input.stratsView == 2",fluidRow(column(12, plotOutput("stratPlot"))))
                   ),
                   
                   ### Deleting the following conditional panel also resolves the well panel issue ###
                   conditionalPanel(condition = "input.selectData == 'DnL balances'",
                     fluidRow(
                       column(12,
                         glide(
                           custom_controls = div(class = "glide-controls", glideControls()),
                           screen(
                             wellPanel(
                                radioButtons(
                                  inputId = 'groupBal',
                                  label = NULL,
                                  choiceNames = c('Calendar period','MOB'),
                                  choiceValues = c('Period','MOB'),
                                  selected = 'Period',
                                  inline = TRUE),
                             style = "padding-top: 12px; padding-bottom: 0px;")
                           )
                         )
                       )
                     )
                   ), # closes conditional panel
                   
                   ### Deleting the following conditional panel (or either checkbox... or selectize...) also resolves the well panel issue ###
                   conditionalPanel(condition = "input.selectData == 'Level 1 data'",
                     panel(
                       checkboxGroupInput(
                         inputId = "vars",
                         label = "Filter by (default view is all data):",
                         choices = c("Period", "MOB"),
                         selected = c("Period", "MOB"),
                         inline = TRUE),
                       selectizeGroupUI(
                         id = "my-filters",
                         params = list(Period = list(inputId = "Period", title = "Period:"),
                                       MOB = list(inputId = "MOB", title = "MOB:"))
                       ), # closes above selectize...
                       status = "primary"
                     )
                   ) # closes conditional panel
          ), id = "tabselected"  
        ) 
      ) 
    ) 
  ) 

server <- function(input, output, session) {}

shinyApp(ui, server)

enter image description here

enter image description here


Solution

  • Actually this is the same issue as here.

    The conditionalPanels are visible for a very short time when first invoking the app.

    This causes a vertical scrollbar to appear and leads to the misalignment.

    Use style = "display: none;" to render the conditionalPanels hidden on startup (where needed) and please leave a thumbs up or other feedback here.

    library(shiny)
    library(shinyjs)
    library(shinyglide)
    library(shinyWidgets)
    
    ui <- 
      fluidPage(
        useShinyjs(),
        tags$style(".glide-controls { position: absolute; top: 8px; right: 14px; width: 160px; }"), 
        titlePanel("Hello"),
        sidebarLayout(
          sidebarPanel(selectInput("selectData", h5(strong("Select data to view:")),choices = list("Stratification","DnL balances"),selected = "Stratification")),
          mainPanel(
            tabsetPanel(
              tabPanel("Private data", value = 1,
                       div(style = "margin-top:10px"),
                       conditionalPanel(condition = "input.selectData == 'Stratification'",
                                        fluidRow(
                                          column(12,
                                                 glide(
                                                   custom_controls = div(class = "glide-controls", glideControls()), 
                                                   screen(
                                                     wellPanel(
                                                       radioButtons(
                                                         inputId = 'groupStrats',
                                                         label = NULL,
                                                         choiceNames = c('Calendar period','MOB'),
                                                         choiceValues = c('Period','MOB'),
                                                         selected = 'Period',
                                                         inline = TRUE), 
                                                       style = "padding-top: 12px; padding-bottom: 0px;") 
                                                   ), 
                                                   screen(
                                                     wellPanel(
                                                       radioButtons(
                                                         inputId = 'stratsView',
                                                         label = NULL,
                                                         choices = list("Table view" = 1,"Plot view" = 2),
                                                         selected = 1,
                                                         inline = TRUE), 
                                                       style = "padding-top: 12px; padding-bottom: 0px;") 
                                                   ) 
                                                 ) 
                                          ) 
                                        ),
                                        ### Deleting next line resolves the well panel issue ###
                                        conditionalPanel(condition = "input.stratsView == 2", style = "display: none;", fluidRow(column(12, plotOutput("stratPlot"))))
                       ),
                       
                       ### Deleting the following conditional panel also resolves the well panel issue ###
                       conditionalPanel(condition = "input.selectData == 'DnL balances'", style = "display: none;",
                                        fluidRow(
                                          column(12,
                                                 glide(
                                                   custom_controls = div(class = "glide-controls", glideControls()),
                                                   screen(
                                                     wellPanel(
                                                       radioButtons(
                                                         inputId = 'groupBal',
                                                         label = NULL,
                                                         choiceNames = c('Calendar period','MOB'),
                                                         choiceValues = c('Period','MOB'),
                                                         selected = 'Period',
                                                         inline = TRUE),
                                                       style = "padding-top: 12px; padding-bottom: 0px;")
                                                   )
                                                 )
                                          )
                                        )
                       ), # closes conditional panel
                       
                       ### Deleting the following conditional panel (or either checkbox... or selectize...) also resolves the well panel issue ###
                       conditionalPanel(condition = "input.selectData == 'Level 1 data'", style = "display: none;",
                                        panel(
                                          checkboxGroupInput(
                                            inputId = "vars",
                                            label = "Filter by (default view is all data):",
                                            choices = c("Period", "MOB"),
                                            selected = c("Period", "MOB"),
                                            inline = TRUE),
                                          selectizeGroupUI(
                                            id = "my-filters",
                                            params = list(Period = list(inputId = "Period", title = "Period:"),
                                                          MOB = list(inputId = "MOB", title = "MOB:"))
                                          ), # closes above selectize...
                                          status = "primary"
                                        )
                       ) # closes conditional panel
              ), id = "tabselected"  
            ) 
          ) 
        ) 
      ) 
    
    server <- function(input, output, session) {}
    
    shinyApp(ui, server)