首页 > 解决方案 > 如何正确使用 Javascript 来定位 Shiny 中的 gt 表行元素

问题描述

我正在用 gt 表制作一个闪亮的应用程序。
如果大写,我想将 .gt_group_heading 类中的文本设为粗体。

似乎传递给该元素的任何文本都是在 td 标记中作为纯文本创建的,而不是被识别为 HTML。

所以我在想也许我可以使用 Javascript 改变文本的外观?

当我运行应用程序时,我无法让脚本工作。
我收到以下错误:

Uncaught TypeError: Cannot read property 'innerHTML' of null
at (index):22 

但是,当我运行该应用程序,然后直接在浏览器控制台中键入 javascript 时,我能够将大写文本显示为粗体。

那么是不是关于闪亮的东西会阻止代码正确运行?似乎我需要在创建 GT 表后运行代码,也许这就是错误消息抛出 null 的原因 - 但我不知道如何使事件的顺序发生在闪亮。

仅供参考,我尝试使用 html 标签将字符串包装在 df$name 中,但这不能正确呈现,即以下内容不起作用:

`df$name <- mutate(df$name, paste("<b>", df$name, "</b>"))`    

非常感谢任何帮助。这是我的示例代码。

library(tidyverse)
library(gt)
library(shiny)

df <- tibble(

  name = c("john", "john", "jerry", "jerry", "jack", "jack", "jim", "jim"), 
  day = c("wed", "wed", "thurs", "thurs", "mon", "mon", "tues", "tues"), 
  lotto = c(12, 42, 24, 57, 234, 556, 34, 23), 
  car = c("chevy", "toyota", "honda", "gmc", "tesla", "nissan", "ford", "jeep")

) %>% 
  mutate(name = toupper(name))

options(gt.row_group.sep = "\n")

ui <- fluidPage(

  gt_output("table"),

  tags$script(
    HTML(
  
     "
    var heading = document.querySelector('#one > table > tbody > tr > td');
    var html = heading.innerHTML;
    html = html.replace(/(\b[A-Z]{2,}\b)/g,'<strong>$1</strong>');
    heading.innerHTML = html;

    "
    )
  )



)


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


  output$table <- render_gt(



    df %>% 
      arrange(lotto) %>%
      gt(
    
        id = "one",
        groupname_col = c("name", "day"), 
        rownames_to_stub = TRUE, 
        row_group.sep = getOption("gt.row_group.sep", "\n")
    
      ) %>%
  
      opt_css(
        css = "

    #one .gt_group_heading {

    white-space:pre-wrap;
    word-wrap:break-word;


    }

    "
      )

  )

}

shinyApp(ui, server)

标签: javascriptrshinyshinyjsgt

解决方案


一种可能是延迟 JavaScript 代码的执行setTimeout,例如 2 秒:

setTimeout(function() {
  var heading = document.querySelector('#one > table > tbody > tr > td');
  var html = heading.innerHTML;
  html = html.replace(/(\b[A-Z]{2,}\b)/g, '<strong>$1</strong>');
  heading.innerHTML = html;
}, 2000); // 2000ms = 2s

永远不清楚如何选择一个好的延迟值。另一种可能性是使用间隔,每 100 毫秒执行一次,直到找到对象:

var myinterval = setInterval(function() {
  var heading = document.querySelectorAll('#one > table > tbody > tr > td');
  if(heading) {
    clearInterval(myinterval);
    for(var i=0; i<heading.length; i++){
      var html = heading[i].innerHTML;
      html = html.replace(/(\b[A-Z]{2,}\b)/g, '<strong>$1</strong>');
      heading[i].innerHTML = html;
    } 
  } 
}, 100);

这是 JavaScript 代码。但由于它是从字符串发送的,因此您必须将正则表达式中的反斜杠加倍:/(\\b[A-Z]{2,}\\b)/g.


推荐阅读