In a Shiny app I create radioButtons dynamically on the server and use renderUI to pass this to the client. Now I have a problem of getting the response of the radioButtons (selected item) back for further processing. Below the stripped down version of my problem.
library(shiny)
ui <- shinyUI(pageWithSidebar(
headerPanel("test dynamic radio buttons"),
sidebarPanel(
),
mainPanel(
x <- uiOutput('radioTest'),
actionButton('submit', label = "Submit"),
br(),
print(paste("Radiobutton response is:", "reply()")),
textOutput('text')
)
))
server <- shinyServer(
function(input, output) {
output$radioTest <- renderUI({
options <- c("item 1", "item 2", "item 3")
# The options are dynamically generated on the server
radioButtons('reply', 'What item do you select ?', options, selected = character(0))
})
observe({
input$submit
isolate(
output$text <- renderText({
paste("Radiobutton response is:", "reply()" )
})
)
})
}
)
# Run the application
shinyApp(ui = ui, server = server)
Do you want something like the following?
library(shiny)
ui <- shinyUI(pageWithSidebar(
headerPanel("test dynamic radio buttons"),
sidebarPanel(
),
mainPanel(
x <- uiOutput('radioTest'),
actionButton('submit', label = "Submit"),
br(),
#print(paste("Radiobutton response is:", "reply")),
textOutput('text')
)
))
server <- shinyServer(
function(input, output) {
output$radioTest <- renderUI({
options <- c("item 1", "item 2", "item 3")
# The options are dynamically generated on the server
radioButtons('reply', 'What item do you select ?', options, selected = character(0))
})
observe({
input$submit
isolate(
output$text <- renderText({
paste("Radiobutton response is:", input$reply )
})
)
})
}
)
# Run the application
shinyApp(ui = ui, server = server)
Related
I am trying to reference the values of a reactive variable. I have included the code I have so far below. I am referring to "output$var1" below. This app selects the dataset and based on that dataset produces another selectInput to select a variable.
I am able to render the text if I directly type dataset$area (the first variable of the rock dataset). I would like to render something like "dataset$selvar". Is there a way to do this?
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("dataset", label = "Dataset", choices =c("rock","pressure","cars")),
numericInput(inputId = "obs",
label = "Number of observations to view:",
value=10)
),
mainPanel(
verbatimTextOutput("summary"),
tableOutput("table"),
selectInput("inSelect","Select variable", c("Item A", "Item B")),
textOutput("var1")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
datasetInput<-reactive({
switch(input$dataset,
"rock"=rock,
"pressure"=pressure,
"cars"=cars
)
})
output$summary<- renderPrint({
dataset<- datasetInput()
summary(dataset)
})
output$table<- renderTable({
head(datasetInput(), n=input$obs)
})
observe({
dataset<- datasetInput()
varlist<-colnames(dataset)
updateSelectInput(session,"inSelect",
label="Select variable",
choices=varlist,
selected=head(varlist,1)
)
selvar<-updateSelectInput(session,"inSelect",
label="Select variable",
choices=varlist,
selected=head(varlist,1)
)
output$var1<-renderText({
dataset$area
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
When I try dataset$selvar I get "error i ncat: argument 1 (type 'environment') cannot be bandled by 'cat'
Remove the second updateSelectInput from your observer, move your renderText outside of the observer. and inside the renderText use datasetInput()[[input$inSelect]] to display the select column from the selected dataset.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("dataset", label = "Dataset", choices = c("rock", "pressure", "cars")),
numericInput(
inputId = "obs",
label = "Number of observations to view:",
value = 10
)
),
mainPanel(
verbatimTextOutput("summary"),
tableOutput("table"),
selectInput("inSelect", "Select variable", c("Item A", "Item B")),
textOutput("var1")
)
)
)
server <- function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars
)
})
output$summary <- renderPrint({
dataset <- datasetInput()
summary(dataset)
})
output$table <- renderTable({
head(datasetInput(), n = input$obs)
})
observe({
dataset <- datasetInput()
varlist <- colnames(dataset)
updateSelectInput(session, "inSelect",
label = "Select variable",
choices = varlist,
selected = varlist[[1]]
)
})
output$var1 <- renderText({
datasetInput()[[input$inSelect]]
})
}
# Run the application
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:5275
How can I move from one tab to another using actionButton() when then name of the tab is dynamic in a shiny app?
library(shiny)
ui <- fluidPage(
tabsetPanel(
id="inTabset",
tabPanel("Tab 1",textInput("name","Name"),actionButton("switch_tab", "Go to the third tab")
),
tabPanel("Tab 2", "there!"),
tabPanel(textOutput("TAB3")))
)
server <- function(input, output, session) {
observeEvent(input$switch_tab, {
updateTabsetPanel(session, "inTabset",selected = "Tab 3")
})
output$TAB3<-renderText({
if(input$name==""){
"Tab 3"
}
else{
paste(input$name)
}
})
}
shinyApp(ui = ui, server = server)
Just use tabPanel's value parameter:
From ?tabPanel:
value - The value that should be sent when tabsetPanel reports that this tab is selected. If omitted and tabsetPanel has an id, then
the title will be used.
library(shiny)
ui <- fluidPage(tabsetPanel(
id = "inTabset",
tabPanel(
"Tab 1",
textInput("name", "Name"),
actionButton("switch_tab", "Go to the third tab")
),
tabPanel("Tab 2", "there!"),
tabPanel(textOutput("TAB3"), value = "TAB3")
))
server <- function(input, output, session) {
observeEvent(input$switch_tab, {
updateTabsetPanel(session, "inTabset", selected = "TAB3")
})
output$TAB3 <- renderText({
if (input$name == "") {
"Tab 3"
} else{
paste(input$name)
}
})
}
shinyApp(ui = ui, server = server)
I have a Shiny dashboard with multiple tabs. In one of the tabs, a slow database query fills the choices for a dropdown menu. I want the slow database query to execute only when the relevant tab is selected.
In the following ReprEx, the slowDatabaseQuery is executed at launch and blocks the R process.
library(shiny)
ui <- fluidPage(
tabsetPanel(
tabPanel(
"panel1",
"Panel 1 content"
),
tabPanel(
"panel2",
"Panel 2 content",
selectizeInput(
"selected",
label = "Selector",
choices = NULL
),
verbatimTextOutput("text")
)
)
)
server <- function(input, output, session) {
slowDatabaseQuery <- reactive({
Sys.sleep(5)
return(c("C", "D"))
})
observe(
updateSelectizeInput(
session,
"selected",
choices = slowDatabaseQuery(),
selected = "C",
server = TRUE
)
)
output$text <- renderText(input$selected)
}
shinyApp(ui = ui, server = server)
A partial solution would be using renderUI() instead of updateSelectizeInput(). However, I would like to use the server = TRUE argument which is only available in updateSelectizeInput() and do not like that it would take the UI element a long time to appear.
We can provide your tabsetPanel with an id and observe the selections via observeEvent.
There are two different options in the code below.
The DB query is done each time tab2 is selected.
The DB query is done the first time tab2 is selected in the current shiny-session (commented out).
library(shiny)
ui <- fluidPage(
tabsetPanel(
id = "tabsetPanelID",
tabPanel(
"panel1",
"Panel 1 content"
),
tabPanel(
"panel2",
"Panel 2 content",
selectizeInput(
"selected",
label = "Selector",
choices = NULL
),
verbatimTextOutput("text")
)
)
)
server <- function(input, output, session) {
slowDatabaseQuery <- reactive({
Sys.sleep(5)
return(c("C", "D"))
})
observeEvent(input$tabsetPanelID,{
if(input$tabsetPanelID == "panel2"){
updateSelectizeInput(
session,
"selected",
choices = slowDatabaseQuery(),
selected = "C",
server = TRUE
)
}
})
# observeEvent(input$tabsetPanelID == "panel2", {
# updateSelectizeInput(
# session,
# "selected",
# choices = slowDatabaseQuery(),
# selected = "C",
# server = TRUE
# )
# }, once = TRUE) # should the query be done only once or each time the tab is selected?
output$text <- renderText(input$selected)
}
shinyApp(ui = ui, server = server)
I want to update output data on update button every time.
Here is my code which show the output on update button for the first time I run the code but in runtime if the input is changed, the output is updated automatically.
library(shiny)
ui <- fluidPage(
titlePanel("My Shop App"),
sidebarLayout(
sidebarPanel(
helpText("Controls for my app"),
selectInput("item",
label = "Choose an item",
choices = list("Keyboard",
"Mouse",
"USB",
sliderInput("price",
label = "Set Price:",
min=0, max = 100, value=10),
actionButton ("update","Update Price")
),
mainPanel(
helpText("Selected Item:"),
verbatimTextOutput("item"),
helpText("Price"),
verbatimTextOutput("price")
)
)
)
server <- function(input, output) {
SelectInput <- eventReactive (input$update , {
output$item = renderText(input$item)
output$price = renderText(input$price)
})
output$item <- renderText(SelectInput())
output$price <- renderText(SelectInput())
}
shinyApp(ui = ui, server = server)
Either create a dependency and put them into the reactive and return it:
server <- function(input, output) {
SelectInput <- eventReactive(input$update,{
list(item = input$item, price = input$price)
})
output$item <- renderText(SelectInput()$item)
output$price <- renderText(SelectInput()$price)
}
Or you can isolate, but then you have to add the button reaction to each listener
server <- function(input, output) {
output$item <- renderText({
req(input$update)
input$update
isolate(input$item)
})
output$price <- renderText({
req(input$update)
input$update
isolate(input$price)
})
}
I'm writing a Shiny app with ShinyAce in order to display reactive code. I used the first example of https://trestletech.github.io/shinyAce/ as a base for my code but I have a problem concerning reactive checkboxInput.
I would like to reactively display some code : for example, if I tick a box, then some code appears and if I un-tick it, the code goes back to normal. This works with actionButton (cf example on the website) but I can't figure out why it does not with checkboxInput.
Here's a reproducible example :
library(shiny)
library(shinyAce)
init <- "first text"
ui <- shinyUI(
pageWithSidebar(
headerPanel(""),
sidebarPanel(
actionButton("reset", "Reset"),
checkboxInput("test", "Test", FALSE)
),
mainPanel(
aceEditor(
outputId = "ace",
selectionId = init
)
)
)
)
server <- shinyServer(function(input, output, session) {
observe({
cat(input$ace, "\n")
})
observeEvent(input$reset, {
updateAceEditor(session, "ace", value = init)
})
observeEvent(input$test, {
updateAceEditor(session, "ace", value = "Second text")
})
})
shinyApp(ui = ui, server = server)
This is a slightly modified version of your answer. I'm using the boolean result of the checkbox input to conditionally update the Ace editor.
init <- "first text"
ui <- shinyUI(
pageWithSidebar(
headerPanel(""),
sidebarPanel(
actionButton("reset", "Reset"),
checkboxInput("test", "Test", FALSE)
),
mainPanel(
aceEditor(
outputId = "ace",
value = init
)
)
)
)
server <- shinyServer(function(input, output, session) {
observe({
cat(input$ace, "\n")
print(input$test)
})
observe({
if(input$test){
updateAceEditor(session, "ace", value = "Second text")
} else {
updateAceEditor(session, "ace", value = init)
}})
observeEvent(input$reset, {
updateAceEditor(session, "ace", value = init)
})
})
shinyApp(ui = ui, server = server)