如何正确使用 Javascript 来定位 Shiny 中的 gt 表行元素
Posted
技术标签:
【中文标题】如何正确使用 Javascript 来定位 Shiny 中的 gt 表行元素【英文标题】:How to use Javascript correctly to target gt table row elements in Shiny 【发布时间】:2021-05-18 17:19:54 【问题描述】:我正在使用 gt 表制作一个闪亮的应用程序。 如果大写,我想将 .gt_group_heading 类中的文本加粗。
似乎任何传递给该元素的文本都是在 td 标记中作为纯文本创建的,而不是被识别为 html。
所以我在想也许我可以使用 javascript 来改变文本的外观?
当我运行应用程序时,我无法让脚本运行。 我收到以下错误:
Uncaught TypeError: Cannot read property 'innerHTML' of null
at (index):22
但是,当我运行该应用程序,然后直接在浏览器控制台中键入 javascript 时,我能够将大写文本显示为粗体。
那么,是不是 Shiny 会阻止代码正确运行?似乎我需要在创建 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)
【问题讨论】:
澄清一下:您想让组标题加粗并大写吗?而且您不想使用text_format
和tab_options
,而是使用JavaScript?
我很想找到一种不使用 JavaScript 的方法。但是,我不知道有什么方法可以格式化传递给 groupname_col 的列中的文本。理想情况下,我希望任何带有大写单词的文本都是粗体的。我希望能够灵活地格式化 groupname_col(组标题)中的文本,但我在 gt_table 中看不到这个功能,所以我试图将 javascript 添加到应用程序中......谢谢
【参考方案1】:
一种可能是使用setTimeout
延迟JavaScript 代码的执行,例如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
。
【讨论】:
谢谢 - 不幸的是,当我向应用程序提供您的第二个解决方案 (var myinterval) 时,它不会产生预期的效果。当我检查浏览器控制台时,我看到以下 127.0.0.1/:29 Uncaught SyntaxError: missing ) after argument list。我希望每个 .gt_group_heading 元素中的每个大写单词都是粗体 - 以便所有名称(john、jerry、jack、jim)都是粗体。当我将代码粘贴到我的应用中时,我是否遗漏了什么? @mdb_ftl 第一个解决方案,它有效吗?如果不是,则正则表达式中的反斜杠可能存在问题。也许需要将反斜杠加倍或加倍。 你是对的!我需要在正则表达式中添加额外的 \ - 我还添加了一个循环来定位表中的所有 td 行 - 我已经编辑了您的解决方案,希望这没问题 - 感谢您的帮助以上是关于如何正确使用 Javascript 来定位 Shiny 中的 gt 表行元素的主要内容,如果未能解决你的问题,请参考以下文章
如何正确使用 QGraphicsLinearLayout 和 QGraphicsScene 来定位 QGraphicsItems?