Home > Blockchain >  Shiny: Update a reactive value with textInput() in modalDialog()
Shiny: Update a reactive value with textInput() in modalDialog()

Time:04-07

I Want to update a Value based on a textInput() within an modalDialog(). I found this answer which does work, but it uses reactiveValues() which creates problems in my case further down in my code.

Is there a way to to update my value text through textInput() and modalDialog() without the use of reactiveValues()?

This works

library(shiny)
library(shinyWidgets)

if (interactive()) {
  shinyApp(
    ui <- fluidPage(
      actionBttn("reset", "RESET", style="simple", size="sm", color = "warning"),
      verbatimTextOutput(outputId = "text")
    ),
    server = function(input, output, session) {
      l <- reactiveValues()
      observeEvent(input$reset, {
        # display a modal dialog with a header, textinput and action buttons
        showModal(modalDialog(
          tags$h2('Please enter your personal information'),
          textInput('name', 'Name'),
          textInput('state', 'State'),
          footer=tagList(
            actionButton('submit', 'Submit'),
            modalButton('cancel')
          )
        ))
      })

      # only store the information if the user clicks submit
      observeEvent(input$submit, {
        removeModal()
        l$name <- input$name
        l$state <- input$state
      })

      # display whatever is listed in l
      output$text <- renderPrint({
        if (is.null(l$name)) return(NULL)
        paste('Name:', l$name, 'and state:', l$state)
      })
    }
  )
}

This does not work

It fails to update the value l when I dont use the l <- reactiveValues().

library(shiny)
library(shinyWidgets)

if (interactive()) {
  shinyApp(
    ui <- fluidPage(
      actionBttn("reset", "RESET", style="simple", size="sm", color = "warning"),
      verbatimTextOutput(outputId = "text")
    ),
    server = function(input, output, session) {
      
      l <- NULL
      
      
      
      observeEvent(input$reset, {
        # display a modal dialog with a header, textinput and action buttons
        showModal(modalDialog(
          tags$h2('Please enter your personal information'),
          textInput('name', 'Name'),
          footer=tagList(
            actionButton('submit', 'Submit'),
            modalButton('cancel')
          )
        ))
      })
      
      # only store the information if the user clicks submit
      observeEvent(input$submit, {
        removeModal()
        l <- input$name
      })
      
      # display whatever is listed in l
      output$text <- renderPrint({
        if (is.null(l)) return(NULL)
        paste('Name:', l)
      })
    }
  )
}

CodePudding user response:

renderPrint needs a reactive dependency to be invalidated and re-rendered. Accordingly using a non-reactive variable in this scenario isn't making any sense.

You should rather work on the downstream problems.

Here is another approach using eventReactive:

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  br(),
  actionBttn("reset", "RESET", style="simple", size="sm", color = "warning"),
  verbatimTextOutput(outputId = "text")
)

server <- function(input, output, session) {
  observeEvent(input$reset, {
    # display a modal dialog with a header, textinput and action buttons
    showModal(modalDialog(
      tags$h2('Please enter your personal information'),
      textInput('name', 'Name'),
      footer=tagList(
        actionButton('submit', 'Submit'),
        modalButton('cancel')
      )
    ))
  })
  
  # only store the information if the user clicks submit
  submittedName <- eventReactive(input$submit, {
    removeModal()
    input$name
  })
  
  output$text <- renderPrint({
    req(submittedName())
    paste('Name:', submittedName())
  })
}

shinyApp(ui, server)

Edit: using reactiveVal for the placeholder:

library(shiny)
library(shinyWidgets)

ui <- fluidPage(
  br(),
  actionBttn("reset", "RESET", style="simple", size="sm", color = "warning"),
  verbatimTextOutput(outputId = "text")
)

server <- function(input, output, session) {
  observeEvent(input$reset, {
    # display a modal dialog with a header, textinput and action buttons
    showModal(modalDialog(
      tags$h2('Please enter your personal information'),
      textInput('name', 'Name'),
      footer=tagList(
        actionButton('submit', 'Submit'),
        modalButton('cancel')
      )
    ))
  })
  
  submittedName <- reactiveVal("placeholder")
  
  # only store the information if the user clicks submit
  observeEvent(input$submit, {
    removeModal()
    submittedName(input$name)
  })
  
  output$text <- renderPrint({
    paste('Name:', submittedName())
  })
}

shinyApp(ui, server)
  • Related