【问题标题】:focusing the cursor in textArea after clicking an action button in shiny单击闪亮的操作按钮后将光标聚焦在 textArea 中
【发布时间】:2016-11-16 16:49:59
【问题描述】:

无论如何,我都不是 html 或 JavaScript 方面的专家。所以,我希望你能帮助解决这个问题。

我想我应该提供一个较小版本的应用程序,以便能够解释问题。这是一个简单应用程序的 app.R,它允许用户在 textArea 中编写,比如说一个词。单词的第一个字母将自动作为操作按钮的标签出现,如果用户单击操作按钮,则 textArea 的内容将更新,说明用户写的单词是以元音还是辅音开头。

library(shiny)
library(shinydashboard)

# Define UI for application 
ui <- dashboardPage(
    dashboardHeader(
            title = "page_title"
    ),
    dashboardSidebar(
    ),
    dashboardBody(
            tabBox(title = "app_title",
                    id = "id", width = "800px",
                    tabPanel("tab1)",
                             fluidRow(
                                     column(width = 12,
                                            box(
                                                    status = "info", solidHeader = TRUE,
                                                    collapsible = FALSE,
                                                    width = 12, 
                                                    title = "textInput", 
                                                    tags$textarea(id = "text_input1", rows =  2, cols = 50, "", autofocus = "autofocus"), 
                                                    fluidRow(
                                                            column(width = 12, 
                                                            actionButton("actionbutton1", label = textOutput("actionbutton1_label"))
                                                            )))))),
                    tabPanel("tab2"
                    ))))

# Define server logic 

server <- function(input, output, session) {
    data1 <- eventReactive(input$actionbutton1, {substr(input$text_input1, 1, 1)})
    output$actionbutton1_label <- renderPrint(cat(noquote({substr(input$text_input1, 1, 1)})))
    observe({
            if (input$actionbutton1 == 0) return()
            isolate({
                    if (data1() %in% c("a", "e", "i", "o", "u")) {
                            updateTextInput(session, "text_input1",
                                            value = paste(input$text_input1, "starts with a vowel", "", sep = " "))
                    }
                    else {
                            updateTextInput(session, "text_input1",
                                            value = paste(input$text_input1, "starts with a consonant", "", sep = " "))
                    }
            })
    })}
# Run the application 
shinyApp(ui = ui, server = server)

问题定义: 当你第一次运行上面的应用程序时,你会在 textArea 中看到光标,因为 textArea 标签定义中的参数 autofocus = "autofocus",所以加载时的焦点没有问题。当您单击操作按钮时,光标不再位于 textArea 中。对于这个简单的应用程序,这似乎没有必要,但在实际应用程序的情况下,这很重要,我希望在用户单击操作按钮后光标回到 textArea 中。

问题再次是,每当应用程序的用户单击操作按钮时,光标就会从 textArea 中消失,并且应用程序的用户必须单击文本区域才能使光标返回并继续他/她输入。无论用户使用应用程序界面的其他元素多少次,我都希望通过保持光标始终处于活动状态并聚焦在 textArea 中来为用户节省这种额外的点击。

研究:网上有很多关于如何控制光标位置的帖子。在这些帖子中,我认为,如果我错了,请纠正我,这种方法几乎与我希望完成的目标最相关:

http://www.mediacollege.com/internet/javascript/form/focus.html

我需要帮助的具体是什么

如果你点击上面的链接,你会发现一段非常有趣的html代码,我复制到这里:

<form name="myform2">
<input type="text" name="mytextfield2">
<input type="button" name="mybutton" value="Set Focus"   OnClick="document.myform2.mytextfield2.focus();">
</form>

以下是我希望您能够帮助我的内容,我可以如何以及在何处将此代码嵌入到闪亮的 ui.R 中?当然,我必须为 textArea 和按钮指定一个表单,并且我将相应地更改 textArea 和按钮的名称。我只需要使上面的 html 代码 ui.R 变得友好(可读和可执行)。非常感谢您提供任何帮助。

到目前为止我尝试过但没有成功:

tags$head(HTML("<form name="myform2">
                         <input type="text" name="text_input1">
                         <input type="button" name="addword1" value="Set Focus" OnClick="document.myform2.text_input1.focus();">
                         </form>"))

如您所见,当我将上述代码嵌入到 ui.R 文件中时,语法被打乱了,并且出现了各种语法警告。

可能很重要:我正在使用闪亮的仪表板,并且 textArea 和操作按钮都定义在 dashboardBody 的 tabBox 中的 tabPanel 中。

非常感谢

【问题讨论】:

  • 你的actionButton还有其他用途吗?因为 Shiny 中的 actionButton 已经有一个 onclick 事件,所以您需要使用现有的 onclick 事件读取 actionButton 的值,或者删除/修改现有的 onclick 事件。
  • 您好warmoverflow,操作按钮确实用于更新textArea 内的文本,它成功地做到了这一点。但是,正如我所提到的,在用户单击操作按钮以更新用户在 textArea 中的输入并且实际发生此更新后,光标不再集中在 textArea 中,用户必须在 textArea 内单击才能获取光标再次出现。你怎么看?
  • 你必须paste 一起发短信。您在HTML 函数中编写字符串的方式是错误的。

标签: javascript html r shiny shinydashboard


【解决方案1】:

这是一个你问的工作版本:

library(shiny)
library(shinydashboard)

# Define UI for application 
ui <- dashboardPage(
  dashboardHeader(
    title = "page_title"
  ),
  dashboardSidebar(
  ),
  dashboardBody(tags$head(tags$script(
    'Shiny.addCustomMessageHandler("refocus",
                                  function(NULL) {
                                    document.getElementById("text_input1").focus();
                                  });'
    )),
    tabBox(title = "app_title",
           id = "id", width = "800px",
           tabPanel("tab1",
                    fluidRow(
                      column(width = 12,
                             box(
                               status = "info", solidHeader = TRUE,
                               collapsible = FALSE,
                               width = 12, 
                               title = "textInput", 
                               tags$textarea(id = "text_input1", rows =  2, cols = 50, "", autofocus = "autofocus"), 
                               fluidRow(
                                 column(width = 12, 
                                        actionButton("actionbutton1", label = textOutput("actionbutton1_label"))
                                 )))))),
           tabPanel("tab2"
           ))))

# Define server logic 

server <- function(input, output, session) {
  data1 <- eventReactive(input$actionbutton1, {

    substr(input$text_input1, 1, 1)

    })

  output$actionbutton1_label <- renderPrint(cat(noquote({substr(input$text_input1, 1, 1)})))

  observeEvent(input$actionbutton1,{

    isolate({
      if (data1() %in% c("a", "e", "i", "o", "u")) {
        updateTextInput(session, "text_input1",
                        value = paste(input$text_input1, "starts with a vowel", "", sep = " "))
      }
      else {
        updateTextInput(session, "text_input1",
                        value = paste(input$text_input1, "starts with a consonant", "", sep = " "))
      }

      session$sendCustomMessage(type="refocus",message=list(NULL))

    })

  })}
# Run the application 
shinyApp(ui = ui, server = server)

【讨论】:

    【解决方案2】:

    所以在 UI 方面你需要这样的东西:

    tags$script('
    Shiny.addCustomMessageHandler("myCallbackHandler",
            function(null) {
              document.myform2.text_input1.focus();
            });
    ')
    

    然后在与actionButton相关的observeEvent中调用这个函数:

    session$sendCustomMessage("myCallbackHandler",list(NULL)) 
    

    因此,当您在服务器中调用该自定义处理程序时,它会随时关注输入。您可能需要更改函数中的 javascript 以使您的页面正常工作,因为我不知道 HTML 中对象的名称。

    希望这会有所帮助。

    【讨论】:

    • 嗨,Carl,我在上面的原始帖子中添加了一个小应用程序的脚本,如果你能向我和社区解释如何在这个小应用程序中实施你的策略,那就太棒了,最好通过发布已解决问题的应用程序代码。再次,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2016-02-09
    • 2018-10-09
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2019-03-16
    相关资源
    最近更新 更多