【问题标题】:Copy and paste text in selectizeInput in a Shiny application在 Shiny 应用程序的 selectizeInput 中复制和粘贴文本
【发布时间】:2019-07-11 16:15:05
【问题描述】:

我的 Shiny 应用中有一个 selectizeInput UI 对象,我希望能够复制和粘贴以逗号分隔的输入列表(即从 selectizeInput 复制和粘贴)。

目前我可以从其他地方复制以逗号分隔的输入列表(即 A、B、C、D),然后将其粘贴到我的 selectizeInput 中。粘贴只能使用“Ctrl + V”,而不是“右键单击+粘贴”,但这很好。

我还希望能够从 selectizeInput 对象中复制我的输入,以便将它们粘贴到其他地方。

见下面的代码(第一选择是一个空字符串,“”,因为我不想在开头选择任何东西):

selectizeInput(
    inputId = "genes_list",
    label = "Genes",
    width = "100%",
    multiple = TRUE,
    choices = c("", genes),
    selected = "",
    options = list(
    delimiter = ',',
    create = I("function(input, callback){
        return {
        value: input,
        text: input };
    }")))

我可以使用“Ctrl + A”选择所有输入或使用“Ctrl + 鼠标单击”选择特定输入(我知道输入已被选择,因为它们在选择时会改变颜色),然后是“Ctrl + C”或“Ctrl + X”不工作。此外,右键单击所选输入不提供“复制”选项。

理想情况下,我想使用“Ctrl + A”或“Ctrl + 鼠标单击”来选择我的输入,然后使用“Ctrl + C”来复制它们。

谢谢

【问题讨论】:

标签: javascript r shiny selectize.js shinyjs


【解决方案1】:

这是一个有点冗长的解决方案,但它确实有效。当有人使用复制粘贴快捷方式时,它会将 javascript 行为注入到您的复制到剪贴板/粘贴箱的 selectizeInput 中。

有很多更简洁的方法可以做到这一点,但它们需要更高级的概念,例如单独的 .js 文件。所以这是更简单但更混乱的方式。

下面是代码,因此您可以大致了解它的作用(所有console.log() 位都可以删除,您可以在那里查看所有步骤以及它们是如何发生的。查看您的“控制台”onen 开发工具浏览器,那里有一个控制台面板(它有点像你的应用程序的“厨房门/八卦墙”)。

这是执行此操作的 javascript,下面是添加它的说明。简而言之,它将:

  • 页面加载后
  • 每当有人尝试复制时添加新行为
  • 当有人尝试复制时,检查他们复制的字段是否是选择输入
  • 如果是,抓取其中的文本,用逗号分隔,然后将 thsat 放入剪贴板/pastebin

Javascript 代码:

console.log("page will load now");
document.addEventListener("DOMContentLoaded", function(){
  console.log("page loaded");
  document.addEventListener("copy", (event) => {
    console.log("coppying from item:", event.target);
    const anchorNode = document.getSelection().anchorNode
    if (anchorNode instanceof HTMLElement && anchorNode.classList.contains("selectize-input")) {
       const items = Array.from(anchorNode.getElementsByClassName("item active"))
      const selectedItemsAsString = items.map(i => i.innerText).join(", ")
      console.log("coppied content:", selectedItemsAsString);
      event.clipboardData.setData("text/plain", selectedItemsAsString)
      event.preventDefault()
    }
  })
});

说明在哪里放置它,在你的用户界面的末尾

ui <- fluidPage( some_components_of_yours,
                 selectizeInput(
                       "codeInput", 
                       label = "Codes (if pasting, coma separated)",
                       choices = c("", genes), 
                       multiple = T,
                       options = list(delimiter = ",", create = T), 
                 ),
                 some_components_of_yours, 
                 tags$script(HTML(
                    'HERE IN THESE SINGLE QUOTES PUT THE JAVASCRIPT CODE FROM ABOVE'
                )))

所以看起来有点像这样:

ui <- fluidPage(
                 selectizeInput(
                       "codeInput", 
                       label = "Codes (if pasting, coma separated)",
                       choices = c("", genes), 
                       multiple = T,
                       options = list(delimiter = ",", create = T), 
                 ),
                 tags$script(HTML(
                    '    console.log("page will load now");
    document.addEventListener("DOMContentLoaded", function(){
      console.log("page loaded");
      document.addEventListener("copy", (event) => {
        console.log("coppying from item:", event.target);
        const anchorNode = document.getSelection().anchorNode
        if (anchorNode instanceof HTMLElement && anchorNode.classList.contains("selectize-input")) {
           const items = Array.from(anchorNode.getElementsByClassName("item active"))
          const selectedItemsAsString = items.map(i => i.innerText).join(", ")
          console.log("coppied content:", selectedItemsAsString);
          event.clipboardData.setData("text/plain", selectedItemsAsString)
          event.preventDefault()
        }
      })
    });'
                )))

我的解决方案是基于其他人的这些答案:

【讨论】:

    猜你喜欢
    • 2017-02-08
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2016-09-30
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多