【问题标题】:Shiny: set focus to input in modalDialogShiny:将焦点设置为 modalDialog 中的输入
【发布时间】:2021-05-18 22:37:17
【问题描述】:

我正在尝试将焦点设置到 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)

modalDialog 是使用两个 textInputs 创建的,但没有关注任一输入。如何在第一个输入上强制输入?我想避免额外的点击来将焦点设置在输入上。感谢您的帮助。

【问题讨论】:

    标签: r shiny shinyjs


    【解决方案1】:

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

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

    该事件在 .modal 元素处触发,该元素不存在,但由于事件冒泡,我们可以在 &lt;body&gt; 等处收听此事件,您可以在那里做出反应。

    理论够了,下面是代码(不需要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")
          )
       )
    )
    

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

    【讨论】:

    • 完美!唯一的调整是我的第一个元素是type = :number'numericInput,这按预期工作。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多