Shiny:将焦点设置为 modalDialog 中的输入

Pau*_*pen 6 r shiny shinyjs

我正在尝试将焦点集中在闪亮的textInput地方modalDialog。我在用shinyjs。根据shinyjs文档的指导,我想出了以下代码,但它没有达到我的预期:

library(shiny)
library(shinyjs)

jscode <- "
shinyjs.refocus = function(e_id) {
  document.getElementById(e_id).focus();
}"

# Define UI for application that draws a histogram
ui <- fluidPage(
    shinyjs::useShinyjs(),
    shinyjs::extendShinyjs(text = jscode, functions = "refocus"),
    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30),
            actionButton("show", "Show Modal")
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
    
    observeEvent(input$show, {
        showModal(ui = modalDialog(title = "my modal dialog",
                                   textInput("text_1", label = "text 1"),
                                   textInput("text_2", label = "text 2"),
                                   js$refocus("text_1")))
    })
    
}

# Run the application 
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

modalDialog由两个 s 创建,textInput但不关注任一输入。如何在第一个输入上强制输入?我想避免额外的点击来将焦点设置在输入上。谢谢你的帮助。

tho*_*hal 7

您的问题是,当您js$refocus被调用时,modal尚未设置。如果您在开发工具中打开控制台,您将看到出现错误。

更好的选择是注册一个事件侦听器,该事件侦听器在显示模式时立即触发。查看模态文档,您可以看到,有一个shown.bs.modal事件,在加载模态时会触发该事件。

该事件是在不存在的元素处触发的.modal,但是由于事件冒泡,我们可以在例如处监听这个事件, <body>并且您可以在那里做出反应。

理论已经足够了,这是代码(不需要shinyjs):

library(shiny)

## create an event listener at <body> which fires as soon as the modal is shown
## sets the focus to the first text element (adapt if needed)
jscode <- HTML("$('body').on('shown.bs.modal', (x) => 
                   $(x.target).find('input[type=\"text\"]:first').focus())")

# Define UI for application that draws a histogram
ui <- fluidPage(
   # Application title
   titlePanel("Old Faithful Geyser Data"),
   tags$header(tags$script(type = "text/javascript", jscode)),
   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
         sliderInput("bins",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30),
         actionButton("show", "Show Modal")
      ),
      
      # Show a plot of the generated distribution
      mainPanel(
         plotOutput("distPlot")
      )
   )
)
Run Code Online (Sandbox Code Playgroud)

只需js$refocus从模态中删除该函数就可以了。这是一个显示效果的 gif:

将焦点设置到第一个文本框