使用bslib创建radioGroupButtons时创建工具提示。

huangapple go评论84阅读模式
英文:

Creating tooltip for radioGroupButtons while using bslib

问题

我想为shinywidgets::radiogroupButton(或shiny::radioButton)获取一个工具提示,用于警告用户选择每个选项的后果。我想要实现与此答案中提到的完全相同的输出。问题是上述解决方案在我使用bslib布局我的仪表板时不起作用。

这是在帖子中定义的函数:

# 用于显示工具提示的函数
radioTooltip <- function(id, choice, title, placement = "bottom", trigger = "hover", options = NULL){
  
  options = shinyBS:::buildTooltipOrPopoverOptionsList(title, placement, trigger, options)
  options = paste0("{'", paste(names(options), options, sep = "': '", collapse = "', '", "'}")
  bsTag <- shiny::tags$script(shiny::HTML(paste0("
    $(document).ready(function() {
      setTimeout(function() {
        $('input', $('#", id, "')).each(function(){
          if(this.getAttribute('value') == '", choice, "') {
            opts = $.extend(", options, ", {html: true});
            $(this.parentElement).tooltip('destroy');
            $(this.parentElement).tooltip(opts);
          }
        })
      }, 500)
    });
  ")))
  htmltools::attachDependencies(bsTag, shinyBS:::shinyBSDep)
}

这是我希望能够正常工作的部分:

library(shiny)
library(bslib)

# 小的shiny应用程序
ui <- page_sidebar(title = "App ",
    sidebar = sidebar(
      shinyWidgets::radioGroupButtons("radioSelection", label = "So many options!", choices = c("A", "B", "C")),
      radioTooltip(id = "radioSelection", choice = "A", title = "Button 1 Explanation", placement = "right", trigger = "hover"),
      radioTooltip(id = "radioSelection", choice = "B", title = "Button 2 Explanation", placement = "right", trigger = "hover"),
      radioTooltip(id = "radioSelection", choice = "C", title = "Button 3 Explanation", placement = "right", trigger = "hover")
    ),
    page_fillable(
      column(9,'Plot')
      )
    )

server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)

作为参考,这完美地运行,唯一的区别是这里没有使用bslib函数:

## 如果您改为运行:
ui <- shinyUI(
  fluidPage(
    fluidRow(
      column(3,
        radioGroupButtons("radioSelection", label = "So many options!", choices = c("A", "B", "C"))
      ),
      radioTooltip(id = "radioSelection", choice = "A", title = "Button 1 Explanation", placement = "right", trigger = "hover"),
      radioTooltip(id = "radioSelection", choice = "B", title = "Button 2 Explanation", placement = "right", trigger = "hover"),
      radioTooltip(id = "radioSelection", choice = "C", title = "Button 3 Explanation", placement = "right", trigger = "hover"),
      column(9,'Plot')
      )
    )
  )

我尝试使用上面定义的函数。当您使用bslib函数布局仪表板时,它将停止工作。

英文:

I want to get a tooltip for a shinywidgets::radiogroupButton (or shiny::radioButton) that warns the user about the consecuences of choosing each option, sepparately. I want to achieve the exact same output mentioned in this answer. The problem is the afore-mentioned solution won't work y I lay out my dashboard using bslib.

This is the function defined in the post

# function creeated to display tooltips
radioTooltip &lt;- function(id, choice, title, placement = &quot;bottom&quot;, trigger = &quot;hover&quot;, options = NULL){
  
  options = shinyBS:::buildTooltipOrPopoverOptionsList(title, placement, trigger, options)
  options = paste0(&quot;{&#39;&quot;, paste(names(options), options, sep = &quot;&#39;: &#39;&quot;, collapse = &quot;&#39;, &#39;&quot;), &quot;&#39;}&quot;)
  bsTag &lt;- shiny::tags$script(shiny::HTML(paste0(&quot;
    $(document).ready(function() {
      setTimeout(function() {
        $(&#39;input&#39;, $(&#39;#&quot;, id, &quot;&#39;)).each(function(){
          if(this.getAttribute(&#39;value&#39;) == &#39;&quot;, choice, &quot;&#39;) {
            opts = $.extend(&quot;, options, &quot;, {html: true});
            $(this.parentElement).tooltip(&#39;destroy&#39;);
            $(this.parentElement).tooltip(opts);
          }
        })
      }, 500)
    });
  &quot;)))
  htmltools::attachDependencies(bsTag, shinyBS:::shinyBSDep)
}

This is what I'd like to se working:

library(shiny)
library(bslib)

# small shiny app
ui &lt;- page_sidebar(title = &quot;App &quot;,
    sidebar = sidebar(
      shinyWidgets::radioGroupButtons(&quot;radioSelection&quot;, label = &quot;So many options!&quot;, choices = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;A&quot;, title = &quot;Button 1 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;B&quot;, title = &quot;Button 2 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;C&quot;, title = &quot;Button 3 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;)
    ),
    page_fillable(
      column(9,&#39;Plot&#39;)
      )
    )

server &lt;- function(input, output, session) {}
shinyApp(ui = ui, server = server)

For reference, this work perfectly, the only difference is that no bslib functions are used here

## it works perfectly if you instead run:
ui &lt;- shinyUI(
  fluidPage(
    fluidRow(
      column(3,
        radioGroupButtons(&quot;radioSelection&quot;, label = &quot;So many options!&quot;, choices = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;))
      ),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;A&quot;, title = &quot;Button 1 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;B&quot;, title = &quot;Button 2 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
      radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;C&quot;, title = &quot;Button 3 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
      column(9,&#39;Plot&#39;)
      )
    )
  )

I tried to use the functions defined above. It stops working when you lay out the dashboead using bslib functions.

答案1

得分: 0

  • destroy 替换为 dispose
  • 移除 HTML 依赖
  • 使用普通的单选按钮,而不是 shinyWidgets 的单选按钮
radioTooltip <- function(id, choice, title, placement = "bottom", trigger = "hover", options = NULL){
  
  options = shinyBS:::buildTooltipOrPopoverOptionsList(title, placement, trigger, options)
  options = paste0("{'", paste(names(options), options, sep = "': '", collapse = "', '", "'}"))
  bsTag <- shiny::tags$script(shiny::HTML(paste0("
    $(document).ready(function() {
      setTimeout(function() {
        $('input', $('#", id, "')).each(function(){
          if(this.getAttribute('value') == '", choice, "') {
            opts = $.extend(', options, ', {html: true});
            $(this.parentElement).tooltip('dispose');
            $(this.parentElement).tooltip(opts);
          }
        })
      }, 500)
    });
  ")))
}

library(shiny)
library(bslib)

# small shiny app
ui <- page_sidebar(
  title = "App ",
  sidebar = sidebar(
    radioButtons("radioSelection", label = "So many options!", choices = c("A", "B", "C")),
    radioTooltip(id = "radioSelection", choice = "A", title = "Button 1 Explanation", placement = "right", trigger = "hover"),
    radioTooltip(id = "radioSelection", choice = "B", title = "Button 2 Explanation", placement = "right", trigger = "hover"),
    radioTooltip(id = "radioSelection", choice = "C", title = "Button 3 Explanation", placement = "right", trigger = "hover")
  ),
  page_fillable(
    column(9,'Plot')
  )
)

server <- function(input, output, session) {}

shinyApp(ui = ui, server = server)
英文:

You have to:

  • replace destroy with dispose
  • remove the html dependency
  • use ordinary radio buttons, not those of shinyWidgets
radioTooltip &lt;- function(id, choice, title, placement = &quot;bottom&quot;, trigger = &quot;hover&quot;, options = NULL){
  
  options = shinyBS:::buildTooltipOrPopoverOptionsList(title, placement, trigger, options)
  options = paste0(&quot;{&#39;&quot;, paste(names(options), options, sep = &quot;&#39;: &#39;&quot;, collapse = &quot;&#39;, &#39;&quot;), &quot;&#39;}&quot;)
  bsTag &lt;- shiny::tags$script(shiny::HTML(paste0(&quot;
    $(document).ready(function() {
      setTimeout(function() {
        $(&#39;input&#39;, $(&#39;#&quot;, id, &quot;&#39;)).each(function(){
          if(this.getAttribute(&#39;value&#39;) == &#39;&quot;, choice, &quot;&#39;) {
            opts = $.extend(&quot;, options, &quot;, {html: true});
            $(this.parentElement).tooltip(&#39;dispose&#39;);
            $(this.parentElement).tooltip(opts);
          }
        })
      }, 500)
    });
  &quot;)))
}

library(shiny)
library(bslib)

# small shiny app
ui &lt;- page_sidebar(
  title = &quot;App &quot;,
  sidebar = sidebar(
    radioButtons(&quot;radioSelection&quot;, label = &quot;So many options!&quot;, choices = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;)),
    radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;A&quot;, title = &quot;Button 1 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
    radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;B&quot;, title = &quot;Button 2 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;),
    radioTooltip(id = &quot;radioSelection&quot;, choice = &quot;C&quot;, title = &quot;Button 3 Explanation&quot;, placement = &quot;right&quot;, trigger = &quot;hover&quot;)
  ),
  page_fillable(
    column(9,&#39;Plot&#39;)
  )
)

server &lt;- function(input, output, session) {}

shinyApp(ui = ui, server = server)

使用bslib创建radioGroupButtons时创建工具提示。

答案2

得分: 0

以下是翻译好的部分:

# 使用 `htmltools::tagQuery()` + Bootstrap 工具提示
# 单选按钮带工具提示
# 
# @param explanation 包含要显示在选项工具提示中的说明的字符向量
# @inheritDotParams [shiny::radioButtons]
# @return shiny::tagList
radioButtonsWithTooltip <- function(..., explanations = NULL) {
  radios <- shiny::radioButtons(...)
  choices <- list(...) $choices
  if (is.null(explanations) || is.null(choices)) {
    return(radios)
  }
  radios_tag_q <- htmltools::tagQuery(radios)
  explanations <- rep(explanations, length.out = length(choices))
  labels <- radios_tag_q$find(".radio label")$selectedTags()
  labels <- lapply(seq_along(labels), function(i) {
    label_tag_q <- labels[[i]] |>
      htmltools::tagQuery()
    label_tag_q$addAttrs(
      `data-bs-toggle` = "tooltip",
      `data-bs-title` = explanations[[i]],
      `data-bs-placement` = "right",
      `data-bs-trigger` = "hover focus"
    )
    tags$div(class = "radio", label_tag_q$allTags())
  })
  radios_tag_q$find(".radio")$remove()
  radios_tag_q$append(labels)

  tagList(
    radios_tag_q$allTags(),
    # 在需要时重新初始化工具提示,以处理 `uiOutput` + `renderUI`:
    tags$script(
      shiny::HTML(
        r"{
        tooltipTriggerList = document.querySelectorAll('[data-bs-toggle=\"tooltip\"]');
        tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
        }"
      )
    )
  )
}
# `ui.R`

ui <- bslib::page(
  title = "RadioGroup tooltip",
  theme = bslib::bs_theme(version = 5),
  tags$div(
    class = "container",
    radioButtonsWithTooltip(
      inputId = "dist",
      label = "Distribution type:",
      choices = c(
        "Normal" = "norm",
        "Uniform" = "unif",
        "Log-normal" = "lnorm",
        "Exponential" = "exp"
      ),
      explanations = c(
        "正态分布",
        "这是均匀分布",
        "对数正态分布!",
        "指数分布"
      )
    ),
    tags$p(
      class = "muted",
      "演示一些占位文本",
      tags$a(
        href = "#",
        `data-bs-toggle` = "tooltip",
        `data-bs-title` = "默认工具提示",
        `data-bs-trigger` = "hover focus",
        "内联链接"
      )
    )
  ),
  # 初始化 Bootstrap 工具提示:
  tags$script(
    shiny::HTML(
      r"{
      let tooltipTriggerList = document.querySelectorAll('[data-bs-toggle=\"tooltip\"]');
      let tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
      }"
    )
  )
)
# `server.R`

server <- function(input, output, session) {

}

使用bslib创建radioGroupButtons时创建工具提示。


<details>
<summary>英文:</summary>
You can use `htmltools::tagQuery()` + bootstrap tooltips.
[![tooltip showcase][1]][1]
Here is a reprex of how to achieve that:
```r
#&#39; Radio buttons with tooltip
#&#39; 
#&#39; @param explanation Character vector containing explanations to be shown in
#&#39; the tooltips of the choices
#&#39; @inheritDotParams [shiny::radioButtons]
#&#39; @return shiny::tagList
radioButtonsWithTooltip &lt;- \(..., explanations = NULL) {
radios &lt;- shiny::radioButtons(...)
choices &lt;- list(...)$choices
if (is.null(explanations) || is.null(choices)) {
return(radios)
}
radios_tag_q &lt;- htmltools::tagQuery(radios)
explanations &lt;- rep(explanations, length.out = length(choices))
labels &lt;- radios_tag_q$find(&quot;.radio label&quot;)$selectedTags()
labels &lt;- lapply(seq_along(labels), \(i) {
label_tag_q &lt;- labels[[i]] |&gt; htmltools::tagQuery()
label_tag_q$addAttrs(
`data-bs-toggle` = &quot;tooltip&quot;,
`data-bs-title` = explanations[[i]],
`data-bs-placement` = &quot;right&quot;,
`data-bs-trigger` = &quot;hover focus&quot;
)
tags$div(class = &quot;radio&quot;, label_tag_q$allTags())
})
radios_tag_q$find(&quot;.radio&quot;)$remove()
radios_tag_q$append(labels)
tagList(
radios_tag_q$allTags(),
# re-initialize tooltips incase of `uiOutput` + `renderUI`:
tags$script(
shiny::HTML(
r&quot;{
tooltipTriggerList = document.querySelectorAll(&#39;[data-bs-toggle=&quot;tooltip&quot;]&#39;);
tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl =&gt; new bootstrap.Tooltip(tooltipTriggerEl));
}&quot;
)
)
)
}

ui.R

ui &lt;- bslib::page(
  title = &quot;RadioGroup tooltip&quot;,
  theme = bslib::bs_theme(version = 5),
  tags$div(
    class = &quot;container&quot;,
    radioButtonsWithTooltip(
      inputId = &quot;dist&quot;,
      label = &quot;Distribution type:&quot;,
      choices = c(
        &quot;Normal&quot; = &quot;norm&quot;,
        &quot;Uniform&quot; = &quot;unif&quot;,
        &quot;Log-normal&quot; = &quot;lnorm&quot;,
        &quot;Exponential&quot; = &quot;exp&quot;
      ),
      explanations = c(
        &quot;The normal distribution&quot;,
        &quot;This is the uniform dist&quot;,
        &quot;Log normal here!&quot;,
        &quot;Exponential dwistibushion&quot;
      )
    ),
    tags$p(
      class = &quot;muted&quot;,
      &quot;Placeholder text to demonstrate some&quot;,
      tags$a(
        href = &quot;#&quot;,
        `data-bs-toggle` = &quot;tooltip&quot;,
        `data-bs-title` = &quot;Default tooltip&quot;,
        `data-bs-trigger` = &quot;hover focus&quot;,
        &quot;inline links&quot;
      )
    )
  ),
  # initialize bootstrap tooltips:
  tags$script(
    shiny::HTML(
      r&quot;{
      let tooltipTriggerList = document.querySelectorAll(&#39;[data-bs-toggle=&quot;tooltip&quot;]&#39;);
      let tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl =&gt; new bootstrap.Tooltip(tooltipTriggerEl));
      }&quot;
    )
  )
)

server.R

server &lt;- function(input, output, session) {
  
}

huangapple
  • 本文由 发表于 2023年7月7日 05:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632519.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定