使用shinyjs根据当前活跃的bsplus轮播幻灯片触发事件

Use shinyjs to trigger an event based on the current active bsplus carousel slide

我正在尝试在我闪亮的应用程序中触发一个事件,该事件基于在 modalDialog 中的 bsplus 轮播中处于活动状态的幻灯片,我认为使用 shinyjs 是前进的方向,因为 class 在控制台的数据目标上更改为“活动”,但我的 js 还不够好,无法开始。

我希望触发的事件是显示一个在初始化时隐藏的绝对面板。

分钟示例:

library(shiny)
library(shinyjs)
library(bsplus)

ui <- fluidPage(
  useShinyjs(),
  hidden(
    absolutePanel(
      id = "button1", top = "20%", right = "20%", fixed = TRUE, 
      actionButton(inputId = "bttn_addmarker", label = "button")
                  )
  )
  )

server <- function(input, output, session) {
  showModal(
    modalDialog(
      bs_carousel(id = "examples_carousel",  use_indicators = TRUE) %>%
        bs_set_data(interval = FALSE) %>%
        bs_append("slide where absolute panel should be hidden") %>%
        bs_append("slide where absolute panel should revealed")
    )
  )
}

shinyApp(ui, server)

控制台视图 - 当 data-slide-to="0" 时,我希望隐藏绝对面板

当 data-slide-to="1" 时,我希望显示绝对面板

你说得对,你可以使用 data-slide-to 属性的活动值来显示按钮,但在 javascript 中确实需要相当多的逻辑才能做到这一点。我们可以从如何取消隐藏该按钮开始。当我检查隐藏按钮时,它有 class“shinyjs-hide”,它具有以下 css 规则:

.shinyjs-hide {
    display: none !important;
}

因此,只需在第二个 li 处于活动状态时删除 class 即可显示该按钮,然后在第二个 li 未处于活动状态时将其添加回去将再次隐藏它。这样做非常简单。我们可以创建一个函数来检查 data-slide-to 属性等于 1 的 li 标签是否有 class 活动。如果它处于活动状态,请将隐藏按钮的 class 更改为“shinyjs-show”,这会取消隐藏按钮。如果不是,则将 class 更改为“shinyjs-hide”,这将隐藏按钮。

function checkStatus(){

setTimeout(function(){

if($( `li[data-slide-to='1']` ).attr('class')=='active'){
    
    $('.shinyjs-hide').removeClass().addClass('shinyjs-show');

} else {

    $('.shinyjs-show').removeClass().addClass('shinyjs-hide');    

}

}, 60);



}

现在每次单击左箭头或右箭头时都需要检查此功能。这些有 class“旋转木马控制”。我们可以使用 jQuery 添加 onclick 属性,该属性将被设置为“checkStatus();”即每次单击按钮时 运行 checkStatus() 函数。

$('.carousel-control').attr('onclick', 'checkStatus();');

这需要在页面加载后 运行,这可以在服务器内部使用 shinyjs::runjs() 完成,如下所示:

  session$onFlushed(function() {
    shinyjs::runjs("$('.carousel-control').attr('onclick', 'checkStatus();');
")
  }, once=TRUE)

checkStatus()函数有一个setTimeout()让函数在运行检查之前等待60毫秒,那是因为检查需要在已经切换到的幻灯片上.

像这样将它们放在一个闪亮的应用程序中:


library(shiny)
library(shinyjs)
library(bsplus)

js <- HTML("

function checkStatus(){

setTimeout(function(){

if($( `li[data-slide-to='1']` ).attr('class')=='active'){
    
    $('.shinyjs-hide').removeClass().addClass('shinyjs-show');

} else {

    $('.shinyjs-show').removeClass().addClass('shinyjs-hide');    

}

}, 60);

}


")


ui <- fluidPage(
  useShinyjs(),
  tags$head(tags$script(js)), 
  hidden(
    absolutePanel(
      id = "button1", top = "20%", right = "20%", fixed = TRUE, 
      actionButton(inputId = "bttn_addmarker", label = "button")
    )
  )
)

server <- function(input, output, session) {
  showModal(
    modalDialog(
      bs_carousel(id = "examples_carousel",  use_indicators = TRUE) %>%
        bs_set_data(interval = FALSE) %>%
        bs_append("slide where absolute panel should be hidden") %>%
        bs_append("slide where absolute panel should revealed")
    )
  )
  
  session$onFlushed(function() {
    shinyjs::runjs("$('.carousel-control').attr('onclick', 'checkStatus();');
")
  }, once=TRUE)
  
  
}


shinyApp(ui, server)

给出: