0
votes

I am having a conditionalPanel problem when more than one option is valid.

A part of my code that the user makes two choices in sequence, so that filters are made in the database.

In the first choice, a State will be selected from a list of possibilities. It is important to know that the user can select more than one State.

In the second choice, the City will be selected from a list of possibilities. In this second choice, the user can also select more than one City.

As I said, important information is that the user can select more than one state, so from that multiple choice of states, it should be shown the cities of all selected states.

Everything works fine when the user selects only one state. The problem with my code starts when it selects more than one state, the ConditionalPanel simply disappears (nothing is shown, not even the first option that was already shown). It only appears again when the user removes the selections, keeping only one.

If anyone has a few minutes to help me to sort out this problem I'm facing, I'll be very grateful.

library(shiny)
library(shinydashboard)
library(readr)

state_options <- c("1. Texas", "2. Massachusetts", "3. Colorado")
options_state_texas <- c("Alamo", "Alton", "Angus", "Atlanta", "Aurora", 
                         "Brownsboro", "Premont", "Princeton", "Red Oak",
                        "Staples", "Texas City")
options_state_massachusetts <- c("Boston", "Cambridge", "Chelsea", "Springfield")
options_state_colorado <- c("Aspen", "Aurora", "Avon", "Cortez", "Denver",
                            "Vail")


createMainPanel <- function(index_id) {
    mainPanel(
        width = 12,
        tabsetPanel(
            tabPanel(
                strong("Split"),
                br(),
                box(
                    title = strong("State:"),
                    status = "primary",
                    width = 3,
                    collapsible = TRUE,
                    checkboxGroupInput(
                        inputId = paste0(index_id, "_state"),
                        label = NULL,
                        choices = state_options
                    )
                ),
                conditionalPanel(
                    condition = "input.distribution_of_sales_sub_state == '1. Texas'",
                    box(
                        title = strong("Cities state 1:"),
                        status = "primary",
                        width = 3,
                        collapsible = TRUE,
                        checkboxGroupInput(
                            inputId = paste0(index_id, "_checkbox_city_1"),
                            label = NULL,
                            choices = options_state_texas
                        )
                    )
                ),
                conditionalPanel(
                    condition = "input.distribution_of_sales_sub_state == '2. Massachusetts'",
                    box(
                        title = strong("Cities state 2:"),
                        status = "primary",
                        width = 3,
                        collapsible = TRUE,
                        checkboxGroupInput(
                            inputId = paste0(index_id, "_checkbox_city_2"),
                            label = NULL,
                            choices = options_state_massachusetts
                        )
                    )
                ),
                conditionalPanel(
                    condition = "input.distribution_of_sales_sub_state == '3. Colorado'",
                    box(
                        title = strong("Cities state 3:"),
                        status = "primary",
                        width = 3,
                        collapsible = TRUE,
                        checkboxGroupInput(
                            inputId = paste0(index_id, "_checkbox_city_3"),
                            label = NULL,
                            choices = options_state_colorado
                        )
                    )
                )
            )
        )
    )
}

createTabItem <- function(title, index_id) {
    tabItem(
        tabName <- paste0(index_id, "_tab"),
        h2(title),
        createMainPanel(index_id))
}

createBox <- function(session, index_id, opcoes){
    updateCheckboxGroupInput(
        session,
        index_id,
        choices = c(opcoes))
}

ui <- dashboardPage(
    dashboardHeader(disable = TRUE),
    dashboardSidebar(
        title = img(src='logo.png', height = 60, width = 180, style = "display: block; 
                    margin-left: auto; margin-right: auto;"),
        HTML("<br><br>"),
        width = 230,
        sidebarMenu(
            menuItem(strong("Sales"), tabName = "distribution_of_sales_sub_tab")
        )
    ),
    dashboardBody(
        tabItems(
            createTabItem(strong("Distribution of sales"),
                          "distribution_of_sales_sub")
        )
    )
)


server <- function(input, output, session) { 
    observe({
        createBox(session,"distribution_of_sales_sub_state", state_options)
        createBox(session,"distribution_of_sales_sub_checkbox_city_1", 
                  options_state_texas)
        createBox(session,"distribution_of_sales_sub_checkbox_city_2", 
                  options_state_massachusetts)
        createBox(session,"distribution_of_sales_sub_checkbox_city_3", 
                  options_state_colorado)
    })
}

shinyApp(ui, server)
2
It might be easier to come up with a solution if you use the selectInput option rather than checkbox in which case you can achieve the functionality without using conditionalPanelkrish
Thank's for your time, @krish But if I use the selectInput, the user will not be able to select more than one state at a time, correct? And selecting more than one state is very frequent for analysis.Pedro Cortez
Both selectInput and selectizeInput have an argument called multiple. You can set this to TRUE which will allow multiple selectionskrish
Just in case you think using selectizeInput will be helpful, you can take a look at thiskrish
Now that you have posted the entire code, how do you expect this to work when one selects more than one state? Should the cities be shown in one single menu for all the states or different menus one for each state?krish

2 Answers

2
votes

You need to change your conditions to

condition = "input.distribution_of_sales_sub_state.includes('1. Texas')",

condition = "input.distribution_of_sales_sub_state.includes('2. Massachusetts')",

condition = "input.distribution_of_sales_sub_state.includes('3. Colorado')",

EDIT: SOLUTION FOR QUESTION IN COMMENTS

This definitely is not the best solution but this should give you what you want and a good start to make it better.

library(shiny)
library(shinydashboard)
library(readr)

state_options <- c("1. Texas", "2. Massachusetts", "3. Colorado")
options_state_texas <- c("Alamo", "Alton", "Angus", "Atlanta", "Aurora", 
                         "Brownsboro", "Premont", "Princeton", "Red Oak",
                         "Staples", "Texas City")
options_state_massachusetts <- c("Boston", "Cambridge", "Chelsea", "Springfield")
options_state_colorado <- c("Aspen", "Aurora", "Avon", "Cortez", "Denver",
                            "Vail")

city_options <- c()

createMainPanel <- function(index_id) {
  mainPanel(
    width = 12,
    tabsetPanel(
      tabPanel(
        strong("Split"),
        br(),
        box(
          title = strong("State:"),
          status = "primary",
          width = 3,
          collapsible = TRUE,
          checkboxGroupInput(
            inputId = paste0(index_id, "_state"),
            label = NULL,
            choices = state_options
          )
        ),
        conditionalPanel(
          condition = "input.distribution_of_sales_sub_state != ''",
          uiOutput("city")
        )
      )
    )
  )
}

createTabItem <- function(title, index_id) {
  tabItem(
    tabName <- paste0(index_id, "_tab"),
    h2(title),
    createMainPanel(index_id))
}

createBox <- function(session, index_id, opcoes){
  updateCheckboxGroupInput(
    session,
    index_id,
    choices = c(opcoes))
}

ui <- dashboardPage(
  dashboardHeader(disable = TRUE),
  dashboardSidebar(
    title = img(src='logo.png', height = 60, width = 180, style = "display: block; 
                    margin-left: auto; margin-right: auto;"),
    HTML("<br><br>"),
    width = 230,
    sidebarMenu(
      menuItem(strong("Sales"), tabName = "distribution_of_sales_sub_tab")
    )
  ),
  dashboardBody(
    tabItems(
      createTabItem(strong("Distribution of sales"),
                    "distribution_of_sales_sub")
    )
  )
)


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

  output$city <- renderUI({
    box(
      title = strong("Cities state:"),
      status = "primary",
      width = 3,
      collapsible = TRUE,
      checkboxGroupInput(
        inputId = paste0("distribution_of_sales_sub", "_checkbox_city_1"),
        label = NULL,
        choices = cities()
      )
    )
  })
  city_options1 <- c()
  city_options2 <- c()
  city_options3 <- c()
  cities <- reactive({
    if(c("1. Texas") %in% input$distribution_of_sales_sub_state ){
      city_options1<- c(options_state_texas)
    }
    if (c("2. Massachusetts") %in% input$distribution_of_sales_sub_state) {
      city_options2 <- c(options_state_massachusetts)
    }
    if (c("3. Colorado") %in% input$distribution_of_sales_sub_state ) {
      city_options3 <- c(options_state_colorado)
    }
    city_options <- c(city_options1,city_options2, city_options3)
    city_options <- sort(city_options)
  })


  observe({
    createBox(session,"distribution_of_sales_sub_state", state_options)
    createBox(session,"distribution_of_sales_sub_checkbox_city_1", 
              options_state_texas)
    createBox(session,"distribution_of_sales_sub_checkbox_city_2", 
              options_state_massachusetts)
    createBox(session,"distribution_of_sales_sub_checkbox_city_3", 
              options_state_colorado)
  })
}

shinyApp(ui, server)
0
votes

Your code is not reproducible at all, You should take care of that before posting the question.

Well my guess without proper code and data would be to move all your conditions to server.R. So in ui.R you should create for each state: uiOutput("state1") (its for the first conditional state: Texas), then in server.R:

output$state1 <- renderUI({
 if(any(input$state == '1. Texas')){
box(
                            title = strong("Cities state 1:"),
                            status = "primary",
                            width = 3,
                            collapsible = TRUE,
                            checkboxGroupInput(
                                inputId = "checkbox_city_1"),
                                label = NULL,
                                choices = options_state_texas
                            )}
else{NULL})