在 Shiny 中如何用 JavaScript 改变 UI 元素的属性?

Posted

技术标签:

【中文标题】在 Shiny 中如何用 JavaScript 改变 UI 元素的属性?【英文标题】:How the change attributes of UI elements with JavaScript in Shiny? 【发布时间】:2021-11-28 10:10:02 【问题描述】:

我知道有一个叫做 renderUI 的服务器端方法,但它在某些情况下会导致更新 UI 非常慢,所以我现在依赖 javascript

我的问题是跟随。我想从 shinymaterial 包中更新 material_card 的标题属性。每次我从单独的下拉菜单中选择一个替代项时,我都希望看到更改的标题。

到目前为止,我的 UI 组件列表包含 tags$script() 对象,它应该观察 selectInput 中的变化(带有 id “dropdown”)。

我的代码如下:

library(shinymaterial)
library(shiny)

ui <- material_page(

    titlePanel("Soon to be working JavaScript example!"),

    sidebarLayout(
        sidebarPanel(
            selectInput(
                "dropdown",
                "Dropdown menu",
                c('Hat','Shoes','Jacket')),
                tags$script('
              $(document).on("shiny:inputchanged", function(event) 
                if (event.name === "dropdown") 
                    if(input.dropdown === "Jacket") 
                  //Even this alert is not working, possibly because input.name is not recognized. :(
                  alert("You chose Jacket, now the material card title will be changed to: Jacket selected");
                  //What am I supposed to put here to update the material_card title?
                     else 
                  //...and here as well...
                
              );'
            ),
            material_card(
                depth=5,
                title = 'This value needs to be changed according what was chosen in the dropdown menu!')
        ),
        mainPanel(
           h5('Nothing here!')
        )
    )
)

server <- function(input, output) 

    #The server is empty, as it should. :)


shinyApp(ui = ui, server = server)

我设法让警报在没有 if(input.dropdown === "Jacket") 验证的情况下工作,但这个验证不起作用:很可能 input.dropdown 甚至无法识别,尽管它与条件面板很好地配合.

此外,我更迷失了逻辑:在观察到 selectInput (dropdown) 值的变化之后,我应该如何实际使用 JavaScript 来更新 material_card 标题?

【问题讨论】:

【参考方案1】:
library(shinymaterial)
library(shiny)

ui <- material_page(
  
  titlePanel("Soon to be working JavaScript example!"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput(
        "dropdown",
        "Dropdown menu",
        c('Hat','Shoes','Jacket')),
      tags$script(html('
              $(document).on("shiny:inputchanged", function(event) 
                if (event.name === "dropdown") 
                  if(event.value === "Jacket") 
                    alert("You chose Jacket, now the material card title will be changed to: Jacket selected");
                    $("#mycard>span.card-title").html("Here is the new card title");
                   else 
                  //...and here as well...
                  
                
              );')
      ),
      material_card(
        depth=5,
        title = 'This value needs to be changed according what was chosen in the dropdown menu!',
        id = "mycard"
      )
    ),
    mainPanel(
      h5('Nothing here!')
    )
  )
)

shinyApp(ui, server = function(input,output))

【讨论】:

这个解决方案确实非常好,但是如果我想在选择“夹克”以外的其他选项时将标题更改为“您选择夹克...”以外的内容怎么办? @Aku-VilleLehtimäki $("#mycard&gt;span.card-title").html("You chose " + event.value + ".");【参考方案2】:

一个闪亮的纯 UI 解决方案:

library(shinymaterial)
library(shiny)

dropdownChoices <- c('Hat','Shoes','Jacket')

ui <- material_page(
  
  titlePanel("Soon to be working JavaScript example!"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput(
        "dropdown",
        "Dropdown menu",
        dropdownChoices),
      material_card(
        depth = 5,
        title = lapply(dropdownChoices, function(i)
          conditionalPanel(sprintf('input.dropdown == "%s"', i), i)
        )
      )),
    mainPanel(
      h5('Nothing here!')
    )
  )
)

server <- function(input, output) 

shinyApp(ui = ui, server = server)

【讨论】:

这是一个非常简单优雅的工作解决方案!这是应该实现的方式,而不是使用 JavaScript。谢谢你。 (我知道,在 cmets 中应该避免说“谢谢”,但我还是谢谢你。)

以上是关于在 Shiny 中如何用 JavaScript 改变 UI 元素的属性?的主要内容,如果未能解决你的问题,请参考以下文章

FineReport中如何用JavaScript自定义地图标签

FineReport中如何用JavaScript自定义地图标签

javascript中如何用jquery寻找所需要的标签?

在acrobat9.0中如何用javascript实现pdf文档自动翻页,或鼠标点击画面翻页?

asp.net中如何用/路径来引用js文件?

在html页面中如何用js调用java类