Shiny Splitlayout and Selectinput Issue

Shiny splitLayout and selectInput issue

Here is a potential fix. It appears that the parent div of the dropdown menu has an overflow: auto style, which blocks the dropdown menu. Changing to visible fixes it.

library(shiny)

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

output$select_1 <- renderUI({
selectInput("select_input","select", choices = LETTERS)
})

}

ui <- fluidPage(
splitLayout(
uiOutput("select_1"),
tags$head(tags$style(HTML("
.shiny-split-layout > div {
overflow: visible;
}
")))
)
)

shinyApp(ui = ui, server = server)

SelectInput choices are hidden behind downloadButton in Shiny App

I changed the splitLayout approach and used a fluidRow() with two columns instead.

library(shiny)

ui <- navbarPage(
title = 'StackOverFlow App',
tabPanel(
title = "First Panel",
sidebarLayout(
sidebarPanel = sidebarPanel(
tags$h4("Archive Filter", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center"),
radioButtons(
inputId = "archive.choice",
label = "Select Tasks to Display",
choices = c("Completed" = "archive.completed", "Scheduled" = "archive.scheduled")
),
tags$h4("Create Archive Report", style = "font-weight: 450; margin-top: 0; text-decoration: underline; text-align: center"),
fluidRow(
column(
width = 6,
selectInput(
inputId = "report.month", label = "Select Month",
choices = as.list(month.name)
)
),
column(
width = 6,
selectInput(
inputId = "report.year", label = "Select Year",
choices = (2020:format(Sys.Date(), "%Y")))
)
),
downloadButton('downloadData', 'Download Report', style='z-index:1;')
),
mainPanel = mainPanel()
)
)
)

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

}

shinyApp(ui, server)

Sample Image

To get the job down using splitLayout it would be necesary to change the css z-index property of the selectImput.

Shiny: How to prevent selectInput from being reset by selecting a second selectInput

You can set selected in updateSelectInput to input$food_1 and input$food_2 respectively.

updateSelectInput(
session,
inputId = "food_1",
choices = food_table %>% filter(Food_category == input$cat_1) %>% pull(Food),
selected = input$food_1
)

Complete app code -

library(shiny)
library(dplyr)

categories <- sort(unique(food_table$Food_category))
foods <- sort(unique(food_table$Food))
unit <- sort(unique(food_table$Serving_Unit))

# Create Shiny app

# Define UI
ui <- fluidPage(headerPanel(strong("Carbohydrate Calculator")),

fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_1',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_1',
label = 'Food Item',
choices = foods
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_1",
label = "How much?",
value = "",
min = 0,
max = 100
))
),
fluidRow(
column(
width = 3,
selectInput(
inputId = 'cat_2',
label = 'Food Category',
choices = c("None", categories)
)),
column(
width = 3,
selectInput(
inputId = 'food_2',
label = 'Food Item',
choices = foods
)),
column(
width = 3,
numericInput(
inputId = "actual_serving_2",
label = "How much?",
value = "",
min = 0,
max = 100
))
),

column(8,
tableOutput("my_table"),
span(textOutput("my_message"), style="color:red")
) # Column close

) # fluidPage close

# Define server logic required to draw a histogram
server <- function(input, output, session) {


food_table_1 <- reactive({
food_table %>%
filter(Food_category == input$cat_1) %>%
filter(Food == input$food_1) %>%
mutate(Actual_amount = input$actual_serving_1)
})

food_table_2 <- reactive({
food_table %>%
filter(Food_category == input$cat_2) %>%
filter(Food == input$food_2) %>%
mutate(Actual_amount = input$actual_serving_2)
})



# Combine selections into a single table
combined_tables <- reactive({
do.call("rbind", list(food_table_1(),
food_table_2()
)
) %>%
mutate(Total_Carbs_grams = Carbs_per_Serving * Actual_amount / Serving_Size) %>%
select(Food_category, Food, Serving_Size, Serving_Unit, Actual_amount, Carbs_per_Serving, Total_Carbs_grams, everything())
})


# Render Output table
output$my_table <- renderTable({

combined_tables()

})



# Create observe function which updates the second selectInput when the first selectInput is changed
observe({

updateSelectInput(
session,
inputId = "food_1",
choices = food_table %>% filter(Food_category == input$cat_1) %>% pull(Food),
selected = input$food_1
)

updateSelectInput(
session,
inputId = "food_2",
choices = food_table %>% filter(Food_category == input$cat_2) %>% pull(Food),
selected = input$food_2
)


}) # Observe close
} # Server close

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

Problems with selectInput in Shiny

This is an example on how to do:

library(shiny)
ui<-fluidPage(
titlePanel(title = "Prueba"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Cargar archivo',
accept = c(
'text/csv',
'text/comma-separated-values',
'text/tab-separated-values',
'text/plain',
'.csv',
'.tsv'
)
),selectInput('xcol', 'Variable X', columns())),
mainPanel(h3("Muestra del archivo cargado:"),
tableOutput('contents'),
verbatimTextOutput("summary")
)
)
)
server <- function(input, output, session){
columns <- reactive({
df <- read.table(input$file1$datapath)
names(df)
})
observe({
if(!is.null(input$file1))
updateSelectInput(session, "xcol", choices=columns())})
}

shinyApp(ui, server)

splitLayout in shinydashboard::box

If you place the selectInput inside a div and set the width to 100%, that should give you what you're looking for.

footer = splitLayout(
tags$div(
selectInput("y", NULL, paste(strrep("x", 10), 1:10), width="100%")
),
actionButton("ok", icon("trash")),
cellWidths = c("85%", "15%"),
cellArgs = list(style = "vertical-align: top")
),

selectInput uses correct width

How to prevent the overlapping of two input labels in splitLayout, Shiny, R?

I assume using fluidRow() with column() is an option for you.

Then you could use:

    fluidRow(
column(width = 4,
selectInput(...)
),
column(width = 4,
selectInput(...)
)
)

Note 1:

You can control the width of an input by the width parameter of column().

Note 2:

Sidenote: If you want to use the full width of 12, you also have to set the mainPanel() to 12, see e.g. here:
https://stackoverflow.com/a/44214927/3502164

Full app - reproducible example:

library(shiny)

# Define UI
ui <- fluidPage(
mainPanel(
selectInput(inputId = "A", label = "This is a long lebel with lots of words", choices = letters[1:5], selected = "a"),
selectInput(inputId = "B", label = "This is a long lebel with lots of words", choices = letters[1:5], selected = "a"),
fluidRow(
column(width = 4,
selectInput(inputId = "C", label = "This is a long lebel with lots of words", choices = letters[1:5], selected = "a")
),
column(width = 4,
selectInput(inputId = "D", label = "This is a long lebel with lots of words", choices = letters[1:5], selected = "a")
)
),
# Expand the menu in splitLayout
# From: https://stackoverflow.com/a/40098855/7669809
tags$head(tags$style(HTML("
.shiny-split-layout > div {
display: inline-block;
}
")))
)
)

# Server logic
server <- function(input, output, session){

}

# Complete app with UI and server components
shinyApp(ui, server)

Issue selecting multiple inputs using selectInput

You just need req(), in a couple of places. Try this

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

observeEvent(input$data1, {
if (input$data1 != "All") {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County[df$State %in% input$data1])))
} else {
updateSelectInput(session, "data2", "Select County", choices = c("All", unique(df$County)))
}
}, priority = 2)

observeEvent(c(input$data1, input$data2), {
req(input$data2)
if (input$data2 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$County %in% input$data2])))
} else {
if (input$data1 != "All") {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City[df$State %in% input$data1])))
} else {
updateSelectInput(session, "data3", "Select City", choices = c("All", unique(df$City)))
}
}
}, priority = 1)

filtered_data <- reactive({
temp_data <- df
req(input$data2,input$data3)
if (input$data1 != "All") {
temp_data <- temp_data[temp_data$State %in% input$data1, ]
}
if (input$data2 != "All") {
temp_data <- temp_data[temp_data$County %in% input$data2, ]
}
if (input$data3 != "All") {
temp_data <- temp_data[temp_data$City %in% input$data3, ]
}
temp_data
})

output$table <- renderDT(
filtered_data()
)

}


Related Topics



Leave a reply



Submit