【问题标题】:Set focus in Shiny app to a specific UI element on load将 Shiny 应用程序中的焦点设置为加载时的特定 UI 元素
【发布时间】:2020-04-16 23:16:16
【问题描述】:

加载我的 R Shiny 应用程序后,我想将焦点设置到 selectInput 元素,以便用户可以立即通过上下箭头选择一个项目并按 Enter。

我试图捕获 JavaScript load 事件,将其发送到 R,然后使用 Shiny.addCustomMessageHandler 设置 selectInput 元素的焦点。

作为中间步骤,我还尝试使用来自actionButton 的点击事件来触发元素焦点。虽然我认为大部分部分都应该在代码中,但load 事件不会被传输到服务器,并且焦点部分会被 JavaScript 拾取。

这篇帖子focusing the cursor in textArea after clicking an action button in shiny 也没有帮助我到达终点线。

这是我目前所拥有的:

library(shiny)
ui <- fluidPage(
  tags$head(tags$script('
    window.addEventListener("load", function(){
      alert("Loaded");
      Shiny.setInputValue("loaded", 1) // new identical function to Shiny.onInputChange
    });
 ')),
  tags$head(tags$script('
    Shiny.addCustomMessageHandler("focus", function(null) {
      document.getElementById("select").focus()
    });  
 ')),
  headerPanel("Focus",  windowTitle = "Focus"),
  fluidRow(
    column(width = 2, class = "panel",
           selectInput("select", label = "Your Choice", choices = c("Choice 1", "Choice 2"), selectize = TRUE),
           actionButton("click", "Click")
    ),
    column(width = 10,
           textOutput("text")
    )
  )
)

server = function(input, output, session) {

  observeEvent(input$loaded, {
    session$sendCustomMessage("focus",list(NULL))
    print("Loaded")
  })

  observeEvent(input$select, {
    print("Selected")
  })

  observeEvent(input$click, {
    session$sendCustomMessage("focus",list(NULL))
    print("Clicked")
  })

  output$text <- renderText({

  })
}

shinyApp(ui = ui, server = server)

感谢您的帮助。

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    打开控制台(Ctrl+Shift+i with Chrome),你会看到你的JS代码有一些错误。

    主要是打开应用时shiny还没有准备好,所以找不到Shiny.setInputValue这个功能。

    为确保shiny 已准备就绪,请使用:

    $(document).on("shiny:connected", function(){
      ......
    });
    

    现在,经过多次试验,我发现要“聚焦”的元素并不是整个select元素。它是类selectize-inputdiv 子元素,您可以使用$("#select ~ .selectize-control &gt; .selectize-input") 进行选择。

    最后,要执行的好操作不是focus,而是click。这是完整的应用程序:

    library(shiny)
    
    js <- '
    $(document).on("shiny:connected", function(){
      alert("Loaded");
      Shiny.setInputValue("loaded", 1);
      Shiny.addCustomMessageHandler("focus", function(x){
        $("#select ~ .selectize-control > .selectize-input").click();
      });
    });
    '
    
    ui <- fluidPage(
      tags$head(tags$script(HTML(js))),
      headerPanel("Focus",  windowTitle = "Focus"),
      fluidRow(
        column(width = 2, class = "panel",
               selectInput("select", label = "Your Choice", 
                           choices = c("Choice 1", "Choice 2"), selectize = TRUE),
               actionButton("click", "Click")
        ),
        column(width = 10,
               textOutput("text")
        )
      )
    )
    
    server = function(input, output, session) {
    
      observeEvent(input$loaded, {
        session$sendCustomMessage("focus", list(NULL))
        print("Loaded")
      })
    
      observeEvent(input$select, {
        print("Selected")
      })
    
      observeEvent(input$click, {
        session$sendCustomMessage("focus", list(NULL))
        print("Clicked")
      })
    
      output$text <- renderText({
    
      })
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 谢谢,这很有帮助!我正在查看元素的检查器,但错误的控制台也很有用。
    • 太糟糕了selected 不工作。如果在 selectInput 中移动上/下键时事件已经触发,甚至没有按回车键,那就太好了...
    • 实际上也有一个$("#select).change() 事件......但我没有让它触发。
    • 仅供参考,当我停用selectInput 元素中的selectize 选项时,$("#select).change() 事件也有效,即如果我设置selectize = FALSE。当该项目被选中一次时,鼠标上下移动都会触发另一个更改事件!
    猜你喜欢
    • 1970-01-01
    • 2013-01-24
    • 2021-05-18
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    相关资源
    最近更新 更多