如何使用 shinyjs 修改多个元素的 class

How to modify class of multiple elements using shinyjs

我有一个闪亮的仪表板,可以显示各种元素(highchart 和 ggplot 图、数据表)。用户可以按一些变量进行过滤以创建数据的“groupA”和“groupB”。GroupA 最初是所有数据,GroupB 最初是空的。当用户打开仪表板时,他们将看到 GroupA 的单列元素。通过过滤他们能够将一些数据移动到 groupB,这应该显示在新的第二列中。因此,A 组和 B 组中的每一个在页面上都有相同的元素,只是应用了不同的过滤器。如果 groupB 变空,视图将再次切换到 groupA 元素的单列。GroupA 的列应根据需要调整大小以覆盖整个宽度或宽度的一半。我很难让它以一种在代码上经济的方式工作。

答案 使用元素 ID 来显示和隐藏特定元素。这可行,但仪表板有很多页面,每页有很多元素。所以会涉及到大量的额外代码。

我认为只需将每个元素放在 div 中,class 对应于该组,我就可以应用相同的想法,除了使用 CSS 选择器并一次性捕获所有元素。但这是行不通的。 CSS 选择器似乎没问题,例如当我在控制台的 jQuery 语句中使用它时,我得到了预期的元素。

为了简单起见,下面的代码只是 show/hide groupB 按钮的问题的代表,而不是依赖于数据。

library(shiny)
library(shinyjs)
library(highcharter)

ui <- fluidPage(
  useShinyjs(),
  actionButton("hide","Hide Group B"),
  actionButton("show","Show Group B"),
  fluidRow(
    div(class = "groupA col-sm-12", highchartOutput("plot1A")),
    div(class = "groupB hidden",    highchartOutput("plot1B"))
  ),
  fluidRow(
    div(class = "groupA col-sm-12", highchartOutput("plot2A")),
    div(class = "groupB hidden",    highchartOutput("plot2B"))
  )
)

server <- function(input, output, session) {
  output$plot1A <- output$plot2A <- renderHighchart({hchart(iris$Sepal.Length)})
  output$plot1B <- output$plot2B <- renderHighchart({hchart(iris$Petal.Length)})
  observeEvent(input$show, {
    removeClass(selector = "div.groupA", "col-sm-12")
    addClass(   selector = "div.groupA", "col-sm-6")
    removeClass(selector = "div.groupB", "hidden")
    addClass(   selector = "div.groupB", "col-sm-6")
  })
  observeEvent(input$hide, {
    removeClass(selector = "div.groupA", "col-sm-6")
    addClass(   selector = "div.groupA", "col-sm-12")
    removeClass(selector = "div.groupB", "col-sm-6")
    addClass(   selector = "div.groupB", "hidden")
  })
}

shinyApp(ui, server)

任何人都可以建议如何使这项工作有效,或者甚至是可以有效地满足我需要的不同方法吗?

removeClassaddClass 都有问题,第一个位置参数是 id,而不是 class。

要使其像您想要的 class 那样工作 add/remove,您需要将参数名称 class = xxx 写出:

removeClass(selector = ".groupA", class = "col-sm-12")

添加所有 class 个参数后,您会看到它正在运行,但仍未显示绘图。这是因为输出图在开始时没有高度。

  1. 默认情况下,闪亮不呈现隐藏(0 高度)元素。你需要告诉 shiny 在块 displayed 之后渲染它。要触发它,您需要通过 javascript 触发 element“显示”事件,但我们可以通过 shinyjs 来完成。

  2. 隐藏元素后,您会看到groupB被隐藏了,但是groupA并没有去扩展区域以覆盖整个宽度。这是因为 highcharter 不知道您进行了更改。您需要通过 window“调整大小”事件告诉它。

完整代码如下所示:

library(shiny)
library(shinyjs)
library(highcharter)

ui <- fluidPage(
    useShinyjs(),
    actionButton("hide","Hide Group B"),
    actionButton("show","Show Group B"),
    fluidRow(
        div(class = "groupA col-sm-12", highchartOutput("plot1A")),
        div(class = "groupB hidden",    highchartOutput("plot1B"))
    ),
    fluidRow(
        div(class = "groupA col-sm-12", highchartOutput("plot2A")),
        div(class = "groupB hidden",    highchartOutput("plot2B"))
    )
)

server <- function(input, output, session) {
    output$plot1A <- output$plot2A <- renderHighchart({hchart(iris$Sepal.Length)})
    output$plot1B <- output$plot2B <- renderHighchart({hchart(iris$Petal.Length)})
    observeEvent(input$show, {
        removeClass(selector = ".groupA", class = "col-sm-12")
        addClass(   selector = ".groupA", class = "col-sm-6")
        removeClass(selector = ".groupB", class = "hidden")
        addClass(   selector = ".groupB", class = "col-sm-6")
        show(selector = ".groupB")
    })
    observeEvent(input$hide, {
        removeClass(selector = ".groupA", class = "col-sm-6")
        addClass(   selector = ".groupA", class = "col-sm-12")
        removeClass(selector = ".groupB", class = "col-sm-6")
        addClass(   selector = ".groupB", class = "hidden")
        runjs("$(window).trigger('resize')")
    })
}

shinyApp(ui, server)