Get available options from shiny widget - r

Is it possible to get the available options for a shiny widget (ie. all of the possible checkboxes from a checkboxInput)?
I have some checkbox input where the options available to check are dependent on other input -- they are updated by observers. Then, suppose I want a button that the user can click and the all of the currently available checkboxes will be checked.
Here is an illustrative example, where I try to update the checkboxes using updateCheckboxGroupInput and the variable input$options. However, this doesn't work because input$options is only the currently selected boxes, so the button does nothing.
Is there already variable that contains all the available checkboxes, or is necessary to maintain another reactive variable with this information?
library(shiny)
shinyApp(
shinyUI(
fluidPage(
uiOutput('ui')
)
),
shinyServer(function(session, input, output) {
output$ui <- renderUI({
inputPanel(
checkboxGroupInput('options', 'Current Options:',
choices=letters, selected='a', inline=TRUE),
column(width = 2,
actionButton('subset', 'Subset the options'),
actionButton('selectAll', 'Select All'))
)
})
## Observers for buttons
observeEvent(input$subset,
updateCheckboxGroupInput(session,
inputId='options',
choices=sample(letters, 10),
inline=TRUE)
)
observeEvent(input$selectAll,
updateCheckboxGroupInput(session,
inputId='options',
## *** What do I put here for selected? ***
selected=input$options,
inline=TRUE)
)
})
)

There isn't a simple Shiny builtin way to do that. You'd have to either use JavaScript to see what the options are, or store the options in a reactive variable

Related

In R Shiny, use textOutput to dynamically populate downloadbutton's label

In R Shiny I am trying to dynamically set a download button's label using reactive renderText and textoutput.
It works as expected but the label is always shown in the new line, and hence the button looks wacky next to a regular button
as shown here
Backend logic is -
In server.R, an input field's value is used to generate conditional labels
output$mycustomlabel <- renderText({ if(input$inputtype=="One") return("Download label 1") else return("Download label 2")})
Then in UI.R, that label is used as
downloadButton("download.button.test", textOutput("mycustomlabel"))
Can someone guide why does it display text on new line, and how can I keep it on same line?
If you want to change the button label you probably need to update it with javascript.
An easier approach could be to have two different buttons and use conditional panels to display one of the buttons:
ui <- fluidPage(
radioButtons('inputtype', 'Set label', c('One', 'Two')),
conditionalPanel(
'input.inputtype == "One"',
downloadButton('btn1', 'Download label 1')
),
conditionalPanel(
'input.inputtype == "Two"',
downloadButton('btn2', 'Download label 2')
)
)
Note that with this approach you do need two observers in the server function.
I'm doing this same thing with a dynamic label on a downloadButton. In my case, I want the user to choose between downloading a dataframe as an Excel file or a CSV file.
Here's what I'm doing:
In the ui definition, where you want the button to show up, use
uiOutput( 'myCustomButtonUI' )
In the server definition, include:
output$myCustomButtonUI <- renderUI({
myCustomLabel <- 'Placeholder'
if( input$inputtype == 'One' ) myCustomLabel <- 'Download Label 1'
if( input$inputtype == 'Two' ) myCustomLabel <- 'Download Label 2'
downloadButton( inputId = 'download.button.test',
label = myCustomLabel )
})
output$download.button.text <- downloadHandler(
filename = "<some filename>",
content = .... <go look up downloadHandler() if you're unfamiliar> ..."
)
The idea is that, because you want your button to be dynamic, it needs to be rendered on the server side. The output of the server side is a tiny piece of UI that is placed in your larger UI by the uiOutput function.

Is it possible for reset (actionButton) and submitButton to work independently in Shiny app?

I have a reset (actionButton) and update button (submitButton) in my Shiny app. The problem is that to reset the app, I have to click on the reset button followed by the update button. Is it possible to reset the app without having to click on update?
EDIT: I do want the app to update only after the user explicitly clicks update. This is because in my app they will have the option to select several selectors to filter the data. Happy to use something else other than submitbutton, but so far this has been the only function that worked for the purpose.
In the example below, I have to click on update twice to get the whole app to reset :
library(shiny)
shinyApp(
ui = basicPage(
numericInput("num", label = "Make changes", value = 1),
submitButton("Update", icon("refresh")),
shinyjs::useShinyjs(),
actionButton("reset", "Reset"),
helpText(
"When you click the button above, you should see",
"the output below update to reflect the value you",
"entered at the top:"
),
verbatimTextOutput("value")
),
server = function(input, output) {
# submit buttons do not have a value of their own,
# they control when the app accesses values of other widgets.
# input$num is the value of the number widget.
output$value <- renderPrint({
input$num
})
observeEvent(input$reset, {
shinyjs::reset("num")
})
}
)
I hope someone can enlighten me!
Perhaps actionButton in combination with updateNumericInput() will meet your needs. Try this
library(shiny)
shinyApp(
ui = basicPage(
numericInput("num", label = "Make changes", value = 1),
actionButton("Update", "refresh"),
shinyjs::useShinyjs(),
actionButton("reset", "Reset"),
helpText(
"When you click the button above, you should see",
"the output below update to reflect the value you",
"entered at the top:"
),
verbatimTextOutput("value")
),
server = function(input, output,session) {
# submit buttons do not have a value of their own,
# they control when the app accesses values of other widgets.
# input$num is the value of the number widget.
observeEvent(input$Update, {
output$value <- renderPrint({
isolate(input$num)
})
})
observeEvent(input$reset, {
#shinyjs::reset("num")
updateNumericInput(session,"num",value=1)
})
}
)

R Shiny - Build a tabsetPanel from a list from selectizeInput

I have been trying to develop this tabsetpanel for a while but without success. The goal is to assemble the tabs dynamically. After the user click the search button, the tabs will be assembled from the user's selection in selectizeInput. Each tab will have a specific content. When the user presses the search button again, the tabs must be built again with the information from selectizeInput without duplication.
I appreciate any help.
the result should be like this image:
library(shiny)
ui <- fluidPage(
title = "Examples of DataTables",
sidebarLayout(
sidebarPanel(
selectizeInput(
'state', 'State', choices = state.name, multiple = TRUE
),
actionButton("search", "Search"),
),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("tab1", verbatimTextOutput("tab1"))
)
)
)
)
server <- function(input, output) {
output$tab1 <- renderPrint({
"tab1"
})
}
shinyApp(ui, server)
Well, I figure it out using insertUI and removeUI. To loop the tabsetPanel I used do.call method and voila!!!

R shiny force render of server side input on non active tabItem on loading

I am using R shinyDashboard to create a web app. This app is loaded with landing on some 'overview' tabitem as active. There are also some more tabItems. Assume I have a specific tabItem called 'Settings', where one can control on appearance and filters, which I would like to apply with default values. It uses dynamic values, so it must be located on server side.
The problem is that until I'm not visiting the 'Settings' tabItem, its inputs are not initialized and therefore the 'Overview' tabItem is missing data.
Below is a reproducible very simple example, in which the app should be loaded with the value '10' in the text box (while in practice, it is only populated after visiting 'Settings'):
require(shiny)
require(shinydashboard)
ui<-dashboardPage(skin = "black",
dashboardHeader(
),
dashboardSidebar(
sidebarMenu(
menuItem("Overview", tabName = "overview"),
menuItem("Settings", tabName = "settings") )
),
dashboardBody(
tabItems(
tabItem("overview",
uiOutput("textUI")
),
tabItem("settings",
htmlOutput("FilterUI")
)
)
)
)
server<-shinyServer(function(input, output,session) {
output$FilterUI <- renderUI({
numericInput("selected_filter", "Select value",min=0,max=20,value=10)
})
output$textUI <-renderUI({
box(input$selected_filter)
})
})
shinyApp(ui, server)
Define a reactiveValues or just a reactive() for the variable that you want to be calculated. Assign it a default (10). Refer to that reactive value for the value argument of the numericInput, and for the output$textUI. observeEvent on the numericInput and update the reactiveValues accordingly.

Using conditionalPanel (or other methods) to create a temporary banner that disappears if user navigates away

I want to create a welcome message for when a user first opens the shiny webpage. Currently I have it such that it is constantly on the first tabPanel. Is there a way to make it disappear when the user navigates away and then back to that panel?
fluidRow(
column(width=12,
tabsetPanel(type = "tabs", id = "tabs1",
tabPanel("Express Usage", wellPanel("Welcome! Please select the libraries you are interested in viewing from below and use the tabs to navigate between graphs. It is best to limit your selection to no more than 5 libraries at a time"), plotOutput("express_Plot", height=400)),
tabPanel("Juvenile Usage", plotOutput("juvenile_Plot", height=400)),
tabPanel("test", h3(textOutput("text_test")))))
),
You can set the value attribute for all your tabPanels accordingly.
In this way, you can tell, in server.R, which tab is currently selected by reading input$tabs1, where tabs1 is the id you set for the tabsetPanel.
Replace the wellPanel with a uiOutput element, and update the UI elements according
to:
The current panel.
The times the panel has been visited.
ui.R
library(shiny)
shinyUI(fluidPage(
fluidRow(
column(width=12,
tabsetPanel(type = "tabs", id = "tabs1",
tabPanel("Express Usage",
uiOutput("welcome"), # replace the wellPanel
plotOutput("express_Plot", height=400), value="ex_usage"),
tabPanel("Juvenile Usage", plotOutput("juvenile_Plot", height=400), value="juv_usage"),
tabPanel("test", h3(textOutput("text_test")))), value="test")
)
)
)
server.R
library(shiny)
shinyServer(function(input, output, session){
visits <- reactiveValues(times = 0)
output$welcome <- renderUI({
if (input$tabs1 == "ex_usage") {
isolate(visits$times <- visits$times + 1)
if (isolate(visits$times) == 1) {
return (wellPanel("Welcome! Please select the libraries you are interested in viewing from below and use the tabs to navigate between graphs. It is best to limit your selection to no more than 5 libraries at a time"))
}
else {
return ()
}
}
})
})

Resources