3

I have a textInput field in my shiny app. I want to have a submit button (or Action button which may make more sense?) beside the textInput, so that when text is added to the textInput, the user can click on the button and the only reaction the App takes is to take in that value (not load anything else on the page) How can this be accomplished?

If I use the following code it loads everything.

shinyUI(

textInput("variable", "Add Recomendation", ""), submitButton("Add")

)
Cybernetic
  • 12,628
  • 16
  • 93
  • 132

3 Answers3

4

I think you would need to use an actionButton() with an observer in your server. Also be sure to wrap input$variable in isolate so that it doesn't cause the observer to fire.

Something like this:

UI.R

library(shiny)    

shinyUI(basicPage(

    textInput("variable", "Add Recommendation", ""),
    actionButton("submit", "Add"),
    textOutput("text")

))

server.R

library(shiny)

shinyServer(function(input, output) {

    values <- reactiveValues(variable = NA)

    observe({

        if(input$submit > 0) {

            values$variable <- isolate(input$variable)

        }

    })

    output$text <- renderText({values$variable})

})
Eric
  • 962
  • 8
  • 12
1

An even simpler way would be to add the submit-button directly into the rendering function. The req(input$submit) makes sure that the rendering function listens to button presses. Further we have to isolate() input$variable. Otherwise, the rendering function would not only be called when the button is pressed but also every time input$variable changes.

One difference compared to the previous solutions: while a reactive expression/value may be helpful in more complex applications, we do not need it here and can directly access the value of input$variable.

library(shiny)

ui <- basicPage(
  textInput("variable", "Add Recommendation", ""),
  actionButton("submit", "Add"),
  textOutput("text")
)

server <- function(input, output) {
  output$text = renderText({
    req(input$submit)
    return(isolate(input$variable))
  })
}

# Run the application
shinyApp(ui = ui, server = server)
Jan
  • 4,974
  • 3
  • 26
  • 43
  • 1
    You don't need to wrap `input$submit` with `req()`, and there's also no need to wrap `isolate(input$variable))` with `return()` in this example. – Giovanni Colitti Apr 05 '22 at 23:11
  • `isolate()` *is* needed not only to avoid unnecessary invalidation of `renderText()`, but because (at least from my reading of the OP) the goal is to only render text when the button is clicked--not when new text is entered. Removing `isolate()` would change the reactive behavior of the app. So I wasn't suggesting the removal of `isolate()`. Rather, I was suggesting that wrapping `isolate()` inside `return()` is not needed because `renderText()` automatically returns output from the last line. – Giovanni Colitti Apr 07 '22 at 16:21
  • 1
    Correct, you do not need `req` or `return`. I prefer to use both because is clearer code that explains the purpose of the line and, thus, make the code easier to read. Removing it would *not* change how it works. – Jan Apr 09 '22 at 10:33
  • For a full discussion on why or why not using return() is a good idea: [https://stackoverflow.com/questions/11738823/explicitly-calling-return-in-a-function-or-not](https://stackoverflow.com/questions/11738823/explicitly-calling-return-in-a-function-or-not) – Giovanni Colitti Apr 09 '22 at 19:10
0
library(shiny)

# Define UI for application that draws a histogram
ui <- (basicPage(
  
  textInput("variable", "Add Recommendation", ""),
  actionButton("submit", "Add"),
  textOutput("text")
  
))

# Define server logic required to draw a histogram
server <- function(input, output) {
  name <- reactive({
    return(input$variable)
  }) 
  
  observeEvent(input$submit, {
    output$text = renderText(name())
    
  })
}

# Run the application 
shinyApp(ui = ui, server = server)
  • 2
    Having comments in your code is nice. To make the answer superb maybe consider adding a bit of explaining context outside of the code block. Sometimes just one or two lines of text go a long way. – Andre Wildberg Feb 21 '21 at 14:32