I would like to create alternative UIs for my app depending on URL parameter. Specifically, I'd like to use the drop-down pickerInput from shinyWidgets instead of checkboxGroupInput, but only if parameter mini=TRUE is passed via the URL
library(shinyWidgets)
nazwy=c('Warszawa', 'Krakow', 'Gdansk')
ui<-fluidPage(
if (mini) {
pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
} else {
checkboxGroupInput('miasto', nazwy)
})
Can I somehow do it using the conditionalPanel, or is renderUI my only option?
Alternatively, can I make the pickerInput or the checkboxGroupInput appear depending on the window width?
UPDATE
Option 1 given below is a working answer to my initial question, making UI dependent on URL. Option 2 is a better solution for this particular case - adapting UI to window size. HOWEVER, for option 2 to work properly, one needs another variable to store selections, so that the select/pickerInput doesn't go back to default selection every time window is resized. I edited the code accordingly.
Four options below:
Option 1: Dependent on URL, renderUI
It is possible to make it dependent on the URL, see for example here. Here is an example implementation:
library(shinyWidgets)
library(shiny)
nazwy=c('Warszawa', 'Krakow', 'Gdansk')
ui<-fluidPage(
uiOutput('myUI')
)
server <- function(input,output,session) {
output$myUI <- renderUI({
query <- parseQueryString(session$clientData$url_search)
if (!is.null(query$mini)) {
if(query$mini==TRUE)
{
pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
}
else
{
checkboxGroupInput('miasto', 'choose: ',nazwy)
}
}
else
{
checkboxGroupInput('miasto', 'choose: ',nazwy)
}
})
}
shinyApp(ui,server,options=list(port=7777))
try both http://127.0.0.1:7777/
and http://127.0.0.1:7777/?mini=TRUE
.
Option 2: Dependent on window width, renderUI
If you would want to make it dependent on the window width, here is a possible solution:
library(shinyWidgets)
library(shiny)
nazwy=c('Warszawa', 'Krakow', 'Gdansk')
ui<-fluidPage(
tags$head(tags$script('
var dimension = [0, 0];
$(document).on("shiny:connected", function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
$(window).resize(function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
')),
uiOutput('myUI')
)
server <- function(input,output) {
output$myUI <- renderUI({
req(input$dimension)
if (input$dimension[1]<800) {
pickerInput(inputId = "miasto", choices = nazwy,
selected=isolate(selected_cities()),multiple = TRUE)
} else {
checkboxGroupInput('miasto', 'choose: ',
choices=nazwy, selected=isolate(selected_cities()))
}
})
#store selected value to pass on resizing
selected_cities<-reactive(input$miasto)
}
shinyApp(ui,server)
option 3: Window width + conditionalPanel. NOTE: Does not work as expected.
library(shinyWidgets)
library(shiny)
nazwy=c('Warszawa', 'Krakow', 'Gdansk')
ui<-fluidPage(
tags$head(tags$script('var dimension = [0, 0];
$(document).on("shiny:connected", function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
$(window).resize(function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
')),
conditionalPanel(condition = 'input.dimension[0]>1000',
pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)
),
conditionalPanel(condition = 'input.dimension[0]<=1000',
checkboxGroupInput('miasto', 'choose: ',nazwy))
)
server <- function(input,output) {
}
shinyApp(ui,server)
Option 4: window width + shinyjs
library(shinyWidgets)
library(shiny)
library(shinyjs)
nazwy=c('Warszawa', 'Krakow', 'Gdansk')
ui<-fluidPage(
tags$head(tags$script('var dimension = [0, 0];
$(document).on("shiny:connected", function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
$(window).resize(function(e) {
dimension[0] = window.innerWidth;
dimension[1] = window.innerHeight;
Shiny.onInputChange("dimension", dimension);
});
')),
div(id='div1',pickerInput(inputId = "miasto", choices = nazwy,multiple = TRUE)),
shinyjs::hidden(div(id='div2',checkboxGroupInput('miasto', 'choose: ',nazwy))),
useShinyjs()
)
server <- function(input,output) {
observeEvent(input$dimension,ignoreNULL=T,{
if (input$dimension[1]>1000) {
shinyjs::show('div1')
shinyjs::hide('div2')
} else {
shinyjs::show('div2')
shinyjs::hide('div1')
}
})
}
shinyApp(ui,server)