首页 > 解决方案 > 调用 Shiny.setInputValue 时更新输入 UI

问题描述

考虑这个示例闪亮的应用程序。mtcars您可以输入汽车名称,例如“Valiant”,它会从内置数据集中打印出 MPG 值。我还想让用户点击汽车而不是输入它。我通过生成带有汽车名称的链接列表并编写一些 javascript 在Shiny.setInputValue单击链接时调用来做到这一点。

我注意到单击链接时,服务器状态会更新(即textOutput("MPG")值更改),但文本框不会更新以显示当前值。是否有不同的方法来获取值,以便textInput更新和textOutput更新反应?

library(shiny)

script <- "$(document).on('click', '.name-opt a', function (evt) {
  evt.preventDefault(); Shiny.setInputValue('name',this.dataset.name);
});"

ui <- fluidPage(
  tags$head(tags$script(HTML(script))),
  textInput("name", "Name:"),
  textOutput("MPG"),
  uiOutput("carlist")
)

server <- function(input, output, session) {
  output$carlist <- renderUI({
    tags$ul(
      Map(function(v) tags$li(tags$a(v, href="#", "data-name"=v)), rownames(head(mtcars, 20))), 
      class="name-opt")
  })
  output$MPG <- renderText({
    req(input$name)
    paste(input$name, "mpg:", mtcars[input$name,]$mpg)
  })
}

shinyApp(ui, server)

经测试shiny_1.5.0

标签: rshiny

解决方案


服务器端:您必须在此处创建一个反应值:myinput,然后使用 myinput() 调用它的值。然后你需要观察者触发updateTextInput每当myinput()变化

 myinput = reactive({
    paste(input$name)
  })
  
  observeEvent(myinput(),{
  updateTextInput(session, "name", value = myinput())
  })

整个代码:

library(shiny)

script <- "$(document).on('click', '.name-opt a', function (evt) {
  evt.preventDefault(); Shiny.setInputValue('name',this.dataset.name);
});"

ui <- fluidPage(
  tags$head(tags$script(HTML(script))),
  textInput("name", "Name:"),
  textOutput("MPG"),
  uiOutput("carlist")
)

server <- function(input, output, session) {
  output$carlist <- renderUI({
    tags$ul(
      Map(function(v) tags$li(tags$a(v, href="#", "data-name"=v)), rownames(head(mtcars, 20))), 
      class="name-opt")
  })
  output$MPG <- renderText({
    req(input$name)
    paste(input$name, "mpg:", mtcars[input$name,]$mpg)
  })
  
  myinput = reactive({
    paste(input$name)
  })
  
  observeEvent(myinput(),{
  updateTextInput(session, "name", value = myinput())
  })
}

shinyApp(ui, server)

推荐阅读