In my R shiny application, I would like to have one button to submit one set of inputs (which affect one portion of the output) and another one to submit the remaining inputs (which affect a different portion of the output). The code in the widgets example of the Shiny tutorial uses a submitButton but it seems like all the inputs are delivered when that single button is pressed? Thanks in advance for your help.
Here is an example showing actionButtons controlling reactive components:
library(shiny)
runApp(list(
ui = fluidPage(
titlePanel("Hello Shiny!"),
sidebarLayout(
sidebarPanel(
tags$form(
numericInput('n', 'Number of obs', 100)
, br()
, actionButton("button1", "Action 1")
)
, tags$form(
textInput("text", "enter some text", value= "some text")
, br()
, actionButton("button2", "Action 2")
)
),
mainPanel(
plotOutput('plot')
, textOutput("stext")
)
)
),
server = function(input, output) {
output$plot <- renderPlot({
input$button1
hist(runif(isolate(input$n)))
})
output$stext <- renderText({
input$button2
isolate(input$text )
})
}
)
)
Related
I have a very long shiny syntax in which the tab panels are located right above the control panel. I was wondering to know how can I move the tabs to the main panel (as shown in the below image). I know that one solution could be to define the tab panels inside the main panel but for some reason, I would like to avoid this. Thanks.
Nader
Actual problem
sample code (the problem)
library(shiny)
ui <- fluidPage(
titlePanel("Tabsets"),
tabsetPanel(
tabPanel("Plot"),
tabPanel("Summary"),
tabPanel("Table")),
sidebarLayout(
sidebarPanel(
sliderInput('sampleSize', 'Sample Size',
min=1, max=nrow(dataset), value=min(1000, nrow(dataset)),
step=500, round=0)
),
mainPanel(
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
sample code (possible solution)
library(shiny)
ui <- fluidPage(
titlePanel("Tabsets"),
sidebarLayout(
sidebarPanel(
sliderInput('sampleSize', 'Sample Size',
min=1, max=nrow(dataset), value=min(1000, nrow(dataset)),
step=500, round=0)
),
mainPanel(
tabsetPanel(
tabPanel("Plot"),
tabPanel("Summary"),
tabPanel("Table"))
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
I'm quite new to Shiny and I'm having a hard time to fix the following apparently simple example.
I have the following code:
library(shiny)
u <- fluidPage(
titlePanel("Simple Selectable Reactive Function"),
sidebarLayout(
sidebarPanel(),
mainPanel(
h2("Results"),
fluidRow(column(2,
selectInput("aa", "Choose a function", choices=c("sin","cos","exp"))
),
column(2,
textOutput(outputId = "outputText1")
)
)
))
)
s <- function(input,output){
output$outputText1 <- renderText({
paste("Sample text")
})
}
shinyApp(ui=u,server=s)
All I'm trying to do is to have "Sample text" aligned at the same height on the screen as the drop down box ("sin").
Right now, the words "Sample text" are aligned with the element label "Choose a function".
I checked ?textOutput but it doesn't seem to be very useful.
Thank you
One way is to wrap your textOutput(outputId = "outputText1") with a tags$div and add a top padding.
library(shiny)
u <- fluidPage(
titlePanel("Simple Selectable Reactive Function"),
sidebarLayout(
sidebarPanel(),
mainPanel(
h2("Results"),
fluidRow(column(2,
selectInput("aa", "Choose a function", choices=c("sin","cos","exp"))
),
column(2,
tags$div(textOutput(outputId = "outputText1"), style = "padding-top:30px;")
)
)
))
)
s <- function(input,output){
output$outputText1 <- renderText({
paste("Sample text")
})
}
shinyApp(ui=u,server=s)
Alternative use two fluidRow to make it more responsive.
In this case the label of the selectInput is set to NULL and e.g. a h5 element is used instead.
library(shiny)
u <- fluidPage(
titlePanel("Simple Selectable Reactive Function"),
sidebarLayout(
sidebarPanel(),
mainPanel(
h2("Results"),
fluidRow(column(2, h5(tags$b("Choose a function")))),
fluidRow(column(2, selectInput("aa", label = NULL, choices=c("sin","cos","exp"))),
column(2,textOutput(outputId = "outputText1")))
)
)
)
s <- function(input,output){
output$outputText1 <- renderText({
paste("Sample text")
})
}
shinyApp(ui=u,server=s)
I have a Shiny App that takes a text input and shows it on the main panel (I used this answer to build it):
ui.r:
library(shiny)
shinyUI(fluidPage(
titlePanel("This is a test"),
sidebarLayout(
sidebarPanel(
textInput("text1", "Enter the text", ""),
actionButton("goButton", "Go")
),
mainPanel(
h3(textOutput("text1", container = span))
)
)
)
)
server.r:
shinyServer(function(input, output) {
cap <- eventReactive(input$goButton, {
input$text1
})
output$text1 <- renderText({
cap()
})
})
It worked great until I decided to add a Tabset panel, and show the input on one of the tabs. I modified mainPanel() in ui.r as:
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("t1"),
tabPanel("t2",
tabPanel("t3"), h3(textOutput("text1", container = span)),
)
)
After this change, I am getting an error when launching an app:
ERROR: cannot coerce type 'closure' to vector of type 'character'
Is there something I am missing?
You have to put the content within the tab within the call to tabPanel. Ex:
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel("t1"),
tabPanel("t2"),
tabPanel("t3", h3(textOutput("text1", container = span)))
)
)
Thus, server.R is unchanged from you question, and ui.R becomes:
library(shiny)
shinyUI(
fluidPage(
titlePanel("This is a test"),
sidebarLayout(
sidebarPanel(
textInput("text1", "Enter the text", ""),
actionButton("goButton", "Go")
),
mainPanel(
tabsetPanel(
type = "tabs",
tabPanel("t1"),
tabPanel("t2"),
tabPanel("t3", h3(textOutput("text1", container = span)))
)
)
)
)
)
I'm using conditionalPanel to create a UI that first presents a panel with options to the user and then displays a tabbed dashboard using tabsetPanel. The simple act of adding another tabPabel as shown below somehow prevents the server.R file from running. I've tested using print statements. It seems like the Shiny app is breaking, but I can't find a syntax error or any reason for it to be.
conditionalPanel(
condition = "output.panel == 'view.data'",
tabsetPanel(id = "type",
tabPanel("Script", value = "script",
fluidPage(
br(),
fluidRow(
column(3, uiOutput("script.name")),
column(3, uiOutput("script.message"))
),
hr(),
plotlyOutput("plotly")
)
),
tabPanel("Location", value = "location",
fluidPage(
br(),
fluidRow(
# column(3, uiOutput("id.range"))
),
hr(),
plotlyOutput("plot")
)
)
# when this tabPanel is uncommented it doesn't work
# ,tabPanel("Accelerometer", value = "accelerometer",
# fluidPage(
# br(),
# hr(),
# plotlyOutput("plot")
# )
# ),
)
)
It's not failing because of the additional tabPanel, it's failing because it contains a duplicate reference to output$plot. Each output of the server function can only be displayed once. For example, this runs, but will fail if the duplicated line is uncommented:
library(shiny)
ui <- shinyUI(fluidPage(
# textOutput('some_text'),
textOutput('some_text')
))
server <- shinyServer(function(input, output){
output$some_text <- renderText('hello world!')
})
runApp(shinyApp(ui, server))
A simple solution is to save the results of the render* function to a local variable, which you can then save to two outputs:
library(shiny)
ui <- shinyUI(fluidPage(
textOutput('some_text'),
textOutput('some_text2')
))
server <- shinyServer(function(input, output){
the_text <- renderText('hello world!')
output$some_text <- the_text
output$some_text2 <- the_text
})
runApp(shinyApp(ui, server))
I set up 2 actionButton in my shiny app to insert user input into database and delete one record from DB.
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Phase1",
column(4,uiOutput("Phase1", inline = FALSE),
wellPanel(
actionButton("P1_Add", "Add",icon=icon("plus-circle")),
actionButton("P1_Del", "Del",icon=icon("minus-circle"))
)),
column(6,h1("Phase1 Input data is put here"),dataTableOutput("Phase1_Data"))
),
tabPanel("Phase2",uiOutput("Phase2",inline=FALSE)),
tabPanel("Phase3")
)
)
and i also defined a observe in server.R to response my click. but seems not working
obs_p1_add<-observe({
if(input$P1_Add)
{
cat("just click add button")
cat("test")
print (input$P1_Add)
output$Phase2<- renderUI({
list(h4("ha! change"))
})
}
})
any one can teach me where went wrong? thanks so much!
Your code works for me!
ui.R:
library(shiny)
shinyUI(fluidPage(
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Phase1",
column(4,uiOutput("Phase1", inline = FALSE),
wellPanel(
actionButton("P1_Add", "Add",icon=icon("plus-circle")),
actionButton("P1_Del", "Del",icon=icon("minus-circle"))
)),
column(6,h1("Phase1 Input data is put here"),dataTableOutput("Phase1_Data"))
),
tabPanel("Phase2",uiOutput("Phase2",inline=FALSE)),
tabPanel("Phase3")
)
)
))
server.R:
library(shiny)
shinyServer(function(input, output) {
obs_p1_add<-observe({
if(input$P1_Add)
{
cat("just click add button")
cat("test")
print (input$P1_Add)
output$Phase2<- renderUI({
list(h4("ha! change"))
})
}
})
})
Text renders in second tab after click: