Tuesday, March 15, 2022

[SOLVED] SelectizeGroupUI - Unable to set filter widths, INLINE = TRUE error when AWS deployed

Issue

Within my shiny app, I have used selectizeGroupUI as part of my dependent selectinputs. I am struggling to manually set the width of the filters to be wider than their titles. See screenshot below. Recommendations are strongly appreciated.

screenshot of the UI rendering with filter width default to title length

The second issue is that when deployed on AWS ubuntu, INLINE = TRUE is not applying to all selecinputs. See in the screenshot below. Ubuntu is running shinyWidgets 0.6.3, shiny 1.7.1.

screenshot of deployed app with one of the filters errored as horizonal when INLINE = TRUE

OYCF_PDE_Entities <- dbGetQuery(con,
                     "SELECT * FROM oycf_pde_entities")
geocodes_penn_counties <- dbGetQuery(con,
                                     "SELECT * FROM geocodes_penn_counties")

#Define the UI
ui <- fluidPage(
  tags$head(
    tags$style(HTML("hr {border-top: 1px solid #1D5C91;}"))
  ),
  theme = bs_theme(version = 5, bootswatch = "materia"),
  titlePanel(img(src = "PDE.jpg",height=150, width= 150)),
  
  sidebarLayout(
    sidebarPanel(
      h4(strong("Query the PDE/OCYF Database")),
      h5(strong("Purpose")),
      p("This application is designed for performing custom queries to a database containing information about private and non-public 
      entities who are serving school-aged children and youth in the Commonwealth of Pennsylvania. Sites in this database include private or non-public licensed schools, as well 
        as non-public entities such as residential and juvenile justice institutions."),
      p(strong("How to Search")),
      tags$ol(
        tags$li("The database provides information at the site-level, as well as by several higher-order aggregates, including region, county, city, type of service, PDE Educational Entity and DHS Entity."),
        tags$li("Use the drop-down filters within this menu to perform a custom query that automatically displays in the table. Selecting one or more values fromm the filters will automatically remove irrelevant values from the rest of the filters. You can also use the filters in any order. They will still show only relevant options."),
        tags$li("The search function at the top right of the table accepts words and/or whole numbers. The search function looks across all columns for all entities in the database and displays every entity with a column containing the number and/or word that was typed."),
        tags$li("Use the first drop down box to select multiple fields from the database. Your choices will be displayed automatically in the table. The application defaults to showing several key fields. Use backspace")
        ),
      selectInput(
        "vars",
        strong("Select Fields"),
        names(OYCF_PDE_Entities),
        selected = c("DHS_ENTITY_NAME","CITY","COUNTY","REGION","ADMINISTRATIVE_UNIT_AUN"),
        selectize = TRUE,
        multiple=TRUE),
      selectizeGroupUI( 
        id="my_filters",
        inline= TRUE,
        params = list(
          REGION = list(inputId="REGION",title="Select Region",placeholder='select'), 
          COUNTY = list(inputId="COUNTY",title="Select County",placeholder='select'),
          CITY = list(inputId="CITY",title="Select City",placeholder='select'),
          DHS_TYPE_OF_SERVICE = list(inputId="DHS_TYPE_OF_SERVICE",title="Select Type of Service",placeholder='select'),
          PDE_EDUCATIONAL_ENTITY = list(inputId="PDE_EDUCATIONAL_ENTITY",title="Select PDE Educational Entity",placeholder='select'),
          DHS_ENTITY_NAME = list(inputId="DHS_ENTITY_NAME",title="Select DHS Entity",placeholder='select')
          ),
        btn_label="Reset All Filters"
        ),
      p("For technical support, please contact [email protected]",
        style = "font-family:'arial';font-size:11pt;color:#1D5C91",align = "center")
    ),
    mainPanel(
      tabsetPanel(
        tabPanel("Database",
                 br(),
                 DT::dataTableOutput("MainTable")),
        tabPanel("Map of Entities in Database",
                 br(),
                 plotOutput("entitymap", height="900px",width="1000px")
                 )

    ))
  )
)

server <- function(input,output,session){
#create reactive environment for database
  rv <- reactiveValues(alldata=data.frame(OYCF_PDE_Entities))
  
#set up the table's server module
DHSTable <- callModule(
  module = selectizeGroupServer,
  id = "my_filters",
  data = rv$alldata,
  vars = c("REGION","COUNTY","CITY","DHS_TYPE_OF_SERVICE","PDE_EDUCATIONAL_ENTITY","DHS_ENTITY_NAME")
)

#output the filtered data to data table UI
  output$MainTable <- DT::renderDataTable({
    DHSTable() %>% select(all_of(input$vars))
  })

#output map of entities across the state of PA
  
output$entitymap <- renderPlot({
  ggplot() +
    geom_polygon(
      mapping = aes(lon,lat,group = group),
      data = geocodes_penn_counties,
      fill="#1D5C91",colour = "deepskyblue3") +
    geom_point(data = DHSTable(), mapping = aes(x = lon, y = lat),colour ="cyan1",size = 1.5) +
    theme_bw() + 
    theme(panel.border = element_blank(), 
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          axis.line = element_blank(),
          axis.ticks = element_blank(),
          axis.title = element_blank(),
          axis.text = element_blank()) +
    coord_quickmap()
  })
  
#Query Results - When filters are changed, update the count from the table even if looking at the map (table not loaded)
  
#reactive expression
  records_reactive <- eventReactive(
    input$MainTable_rows_all,{
      NROW(input$MainTable_rows_all)
    }
  )

  #output record count
  output$recordsreturned <- renderText(paste("Number of Records:",records_reactive()))
  
#summary, not filter dependent
output$descriptive1 <- renderText(paste("Total Number of Records in Database:",nrow(OYCF_PDE_Entities)))

}

#Run the app
shinyApp(ui = ui,server = server)

Solution

I think I know what the issue is. As of shinyWidgets version 0.6.3 you'll need to repeat the inline argument in the callModule-call.

This change was required due to this issue.

Please see my comment in the server part of the below example:

library(shiny)
library(shinyWidgets)

data("mpg", package = "ggplot2")

ui <- fluidPage(
  titlePanel("Hello Shiny!"),
  sidebarLayout(
    sidebarPanel(
      selectizeGroupUI(
        id = "my-filters",
        params = list(
          manufacturer = list(inputId = "manufacturer", title = "Manufacturer:"),
          model = list(inputId = "model", title = "Model:"),
          trans = list(inputId = "trans", title = "Trans:"),
          class = list(inputId = "class", title = "Class:")
        ),
        inline = FALSE
      )
    ),
    mainPanel(
      DT::dataTableOutput(outputId = "table")
    )
  )
)

server <- function(input, output) {
  res_mod <- callModule(
    module = selectizeGroupServer,
    id = "my-filters",
    data = mpg,
    vars = c("manufacturer", "model", "trans", "class"),
    inline = FALSE # switch to TRUE to see the issue
  )
  output$table <- DT::renderDataTable(res_mod())
}


Answered By - ismirsehregal
Answer Checked By - Senaida (WPSolving Volunteer)