Search code examples
rshinyshinyjs

Why does shinyjs::reset clobber subsequent updateTextInput commands?


The new name value is not getting set after the reset when "Fill example name" is hit

library(shiny)
shinyApp(
  ui = fluidPage(
    shinyjs::useShinyjs(),
    shinyjs::inlineCSS(list(.big = "font-size: 2em")),
    div(id = "myapp",
        h2("shinyjs demo"),
        checkboxInput("big", "Bigger text", FALSE),
        textInput("name", "Name", ""),
        a(id = "toggleAdvanced", "Show/hide advanced info", href = "#"),
        shinyjs::hidden(
          div(id = "advanced",
              numericInput("age", "Age", 30),
              textInput("company", "Company", "")
          )
        ),
        p("Timestamp: ",
          span(id = "time", date()),
          a(id = "update", "Update", href = "#")
        ),
        actionButton("submit", "Submit"),
        actionButton("reset", "Reset form"),
        actionButton("example", "Fill example name")
    )
  ),

  server = function(input, output, session) {
    observe({
      shinyjs::toggleState("submit", !is.null(input$name) && input$name != "")
    })

    shinyjs::onclick("toggleAdvanced",
                     shinyjs::toggle(id = "advanced", anim = TRUE))

    shinyjs::onclick("update", shinyjs::html("time", date()))

    observe({
      shinyjs::toggleClass("myapp", "big", input$big)
    })

    observeEvent(input$submit, {
      shinyjs::alert("Thank you!")
    })

    observeEvent(input$reset, {
      shinyjs::reset("myapp")
    })

    observeEvent(input$example, {
      shinyjs::reset("myapp")
      shiny::updateTextInput(session, "name", value = "Joe Schmoe")
    })
  }
)

Solution

  • The issue is, that shinyjs::reset and updateTextInput are firing in the same reactive cycle.

    We can exclude input$name from the reset:

    library(shiny)
    shinyApp(
      ui = fluidPage(
        shinyjs::useShinyjs(),
        shinyjs::inlineCSS(list(.big = "font-size: 2em")),
        div(id = "myapp",
            h2("shinyjs demo"),
            checkboxInput("big", "Bigger text", FALSE),
            textInput("name", "Name", ""),
            a(id = "toggleAdvanced", "Show/hide advanced info", href = "#"),
            shinyjs::hidden(
              div(id = "advanced",
                  numericInput("age", "Age", 30),
                  textInput("company", "Company", "")
              )
            ),
            p("Timestamp: ",
              span(id = "time", date()),
              a(id = "update", "Update", href = "#")
            ),
            actionButton("submit", "Submit"),
            actionButton("reset", "Reset form"),
            actionButton("example", "Fill example name")
        )
      ),
      
      server = function(input, output, session) {
        observe({
          shinyjs::toggleState("submit", !is.null(input$name) && input$name != "")
        })
        
        shinyjs::onclick("toggleAdvanced",
                         shinyjs::toggle(id = "advanced", anim = TRUE))
        
        shinyjs::onclick("update", shinyjs::html("time", date()))
        
        observe({
          shinyjs::toggleClass("myapp", "big", input$big)
        })
        
        observeEvent(input$submit, {
          shinyjs::alert("Thank you!")
        })
        
        observeEvent(input$reset, {
          shinyjs::reset("myapp")
        })
        
        observeEvent(input$example, {
          lapply(setdiff(names(input), "name"), function(x){shinyjs::reset(x)})
          shiny::updateTextInput(session, "name", value = "Joe Schmoe")
        })
      }
    )