【问题标题】:On click for shiny inputs to get last input clicked doesn't work for selectInput or selectizeInput单击闪亮输入以获取最后单击的输入不适用于 selectInput 或 selectizeInput
【发布时间】:2022-11-30 16:56:36
【问题描述】:

我想触发一个包含最后一次点击输入的输入 ID 的反应。我所拥有的对于numericInputtextInput 等一些输入工作正常。但它不适用于 selectInputselectizeInput。我试过在 JS 表达式中使用各种选择器,但没有一个选择器捕获 selectInputselectizeInput

这是一个代表。当您单击前两个输入中的任何一个时,renderText 会更新,但不会更新后两个。

library(shiny)

ui <- fluidPage(
  tags$head(
    tags$script(
      htmlwidgets::JS("$( document ).on('click', '.form-control, .shiny-bound-input, .selectized', function() {
                        Shiny.setInputValue('last_input', this.id);
                      });")
    )
  ),
  
  numericInput("num1", "Numeric", 0),
  textInput("text1", "Text"),
  selectInput("select1", "Select", choices = LETTERS[1:4]),
  selectInput("selectize1", "Selectize", choices = letters[1:4]),
  
  textOutput("textout")
)

server <- function(input, output, session) {
  
  output$textout <- renderText({
    input$last_input
  })
}

shinyApp(ui, server)

【问题讨论】:

  • 我尝试了这个更通用的 JS 表达式,但它也没有用:$(document).ready(function(){ $('input').on('click', function(evt){ Shiny.setInputValue('last_input', evt.target.id); }); })
  • 查看开发者工具,好像shiny的select和selectize有display: none,所以不会触发点击:&lt;select id="select1" tabindex="-1" class="selectized shiny-bound-input" style="display: none;"&gt;&lt;option value="A" selected="selected"&gt;A&lt;/option&gt;&lt;/select&gt;

标签: javascript r shiny


【解决方案1】:

那是因为 id 归因于 select 元素,而您没有单击该元素。

我的第一个想法是搜索第一个具有 id 的父元素:

tags$script(
  HTML("$( document ).on('click', '.form-control, .shiny-bound-input, .selectized', function() {
          var $parentWithId = $(this).closest('*[id]');
          Shiny.setInputValue('last_input', $parentWithId.attr('id'));
        });")
)

但这仍然不适用于selectizeInput

也许你更想:

tags$script(
  HTML("$(document).on('shiny:inputchanged', function(event) {
          Shiny.setInputValue('last_input', event.name);
        });")
)

它返回最后更改的输入的 id。


编辑

正如您在评论中指出的那样,当更改是由 update* 函数从服务器引起的时,此方法还会设置 last_input。以下是如何防止这种情况:

tags$script(
  HTML("$(document)
         .on('shiny:updateinput', function(e) {
            $(e.target).one('shiny:inputchanged', function(ev) {
              ev.stopPropagation();
            });
          })
          .on('shiny:inputchanged', function(e) {
            Shiny.setInputValue('last_input', e.name);
          });")
)

【讨论】:

  • 谢谢,但不幸的是它不适用于我的情况。我正在尝试使用最后一次单击的输入来确定用户是否更改了输入以及是否通过 update* 函数更改了输入。你的建议会导致它触发这两种情况。
  • @WillHipson 你是对的。但是可以防止这种情况发生-请参阅我的编辑。
  • 有什么地方可以找到更多关于使用 JS 阻止更新*函数失效和触发反应的信息/示例吗?这将帮助我完全绕过创建 last_input 反应。
  • 专门针对这个问题创建了一个单独的问题:stackoverflow.com/questions/72101238/…
【解决方案2】:

我遇到了同样的问题,过了一会儿,我找到了解决方案。首先,您必须确定 selectInput 的开头字符串ID: 假设 id 以字符串开头id_name.闪亮的 selectInput 包含在分区单击输入时会发生变化,并且在单击后将所选值分配给选择包含名为的输入 ID 的元素ID.得到ID单击输入时的 selectInput ,您必须在分区通过这样做改变:

tags$head(
tags$script(
HTML(
"$(document).ready(function(){
  $('div').on('change', 'select',function(evt){
    if(evt.target.id.match('^id_name')=='id_name'){
        Shiny.setInputValue('select_id', evt.target.id);
    }
  });
});"
)
)
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-24
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多