-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Improve documentation for submitButton and change 07_widgets example to use an action button #1475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,54 @@ | |
| #' button do not automatically update their outputs when inputs change, | ||
| #' rather they wait until the user explicitly clicks the submit button. | ||
| #' | ||
| #' @section Warning: | ||
| #' Submit buttons are very particular shiny objects. One the weirdest | ||
|
||
| #' things about them is they have no IDs, and there is no way to regulate | ||
| #' which inputs they should (and which ones they should not) be applied | ||
| #' to. This means they are very unwieldy for anything but the simplest | ||
| #' apps (see the example below). For example, having \emph{two} submit | ||
| #' buttons in the same app will probably not do what you'd expect because | ||
| #' submit buttons are not isolated in any way, so activating any of the | ||
| #' two buttons will cause all inputs in the app to fire. Another problem | ||
| #' with submit buttons is that dynamically created submit buttons (for | ||
| #' example, with \code{\link{renderUI}} or \code{\link{insertUI}}) will | ||
| #' not work. | ||
| #' | ||
| #' For all of these reasons, \strong{our general reccomendation is to | ||
| #' avoid submit buttons} and | ||
| #' \href{http://shiny.rstudio.com/articles/action-buttons.html#pattern-2---delay-reactions}{ | ||
| #' use action buttons instead when you want to delay a reaction}. Any | ||
| #' code that uses a submit button can be converted to code that uses an | ||
| #' action button instead (while the reverse is almost never true). So, | ||
| #' if you find your app getting increasingly complicated, opt for using | ||
| #' an action button (or more since there is no problem with multiple | ||
| #' action buttons in the same app). The link above shows an example of | ||
| #' a delayed reaction using an action button. For another example, the | ||
| #' code below converts the example in this page (at the bottom) to an | ||
| #' equivalent app using an action button (using the same pattern | ||
| #' described in the link above): | ||
| #' | ||
| #' \preformatted{ | ||
| #' shinyApp( | ||
|
||
| #' ui = basicPage( | ||
| #' numericInput("num", label = "Make changes", value = 1), | ||
| #' actionButton("update" ,"Update View", icon("refresh"), | ||
| #' class = "btn btn-primary"), | ||
| #' 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) { | ||
| #' currentValue <- eventReactive(input$update, { | ||
| #' input$num | ||
| #' }, ignoreNULL = FALSE) | ||
| #' | ||
| #' output$value <- renderPrint({ currentValue() }) | ||
| #' } | ||
| #' ) | ||
| #' } | ||
| #' | ||
| #' @param text Button caption | ||
| #' @param icon Optional \code{\link{icon}} to appear on the button | ||
| #' @param width The width of the button, e.g. \code{'400px'}, or \code{'100\%'}; | ||
|
|
@@ -13,8 +61,26 @@ | |
| #' @family input elements | ||
| #' | ||
| #' @examples | ||
| #' submitButton("Update View") | ||
| #' submitButton("Update View", icon("refresh")) | ||
| #' if (interactive()) { | ||
| #' | ||
| #' shinyApp( | ||
| #' ui = basicPage( | ||
| #' numericInput("num", label = "Make changes", value = 1), | ||
| #' submitButton("Update View", icon("refresh")), | ||
| #' 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 }) | ||
| #' } | ||
| #' ) | ||
| #' } | ||
| #' @export | ||
| submitButton <- function(text = "Apply Changes", icon = NULL, width = NULL) { | ||
| div( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| This example demonstrates some additional widgets included in Shiny, such as `helpText` and `submitButton`. The latter is used to delay rendering output until the user explicitly requests it. | ||
| This example demonstrates some additional widgets included in Shiny, such as `helpText` and `actionButton`. The latter is used to delay rendering output until the user explicitly requests it (a construct which also introduces two important server functions, `eventReactive` and `isolate`). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,32 @@ | ||
| library(shiny) | ||
| library(datasets) | ||
|
|
||
| # Define server logic required to summarize and view the | ||
| # Define server logic required to summarize and view the | ||
| # selected dataset | ||
| function(input, output) { | ||
|
|
||
| # Return the requested dataset | ||
| datasetInput <- reactive({ | ||
|
|
||
| # Return the requested dataset. Note that we use `eventReactive()` | ||
| # here, which takes a dependency on input$update (the action | ||
| # button), so that the output is only updated when the user | ||
| # clicks the button. | ||
| datasetInput <- eventReactive(input$update, { | ||
| switch(input$dataset, | ||
| "rock" = rock, | ||
| "pressure" = pressure, | ||
| "cars" = cars) | ||
| }) | ||
| }, ignoreNULL = FALSE) | ||
|
|
||
| # Generate a summary of the dataset | ||
| output$summary <- renderPrint({ | ||
| dataset <- datasetInput() | ||
| summary(dataset) | ||
| }) | ||
|
|
||
| # Show the first "n" observations | ||
|
|
||
| # Show the first "n" observations. The use of `isolate()` here | ||
| # is necessary because we don't want the table to update | ||
| # whenever input$obs changes (only when the user clicks the | ||
| # action button). | ||
| output$view <- renderTable({ | ||
| head(datasetInput(), n = input$obs) | ||
| head(datasetInput(), n = isolate(input$obs)) | ||
| }) | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this needs to be a warning -- just having the text in the default section (details) should be fine.