Mastering the art of targeting table row elements in Shiny using Javascript

I'm currently developing a shiny app that incorporates a gt table.
I want to make the text bold in the .gt_group_heading class if it's capitalized.

It appears that any text passed to this element is treated as plain text within the td tag and not recognized as HTML.

My idea was to use Javascript to modify the appearance of the text. However, I'm facing an issue when running the app - I encounter the following error:

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

Interestingly, when I run the app and input the JavaScript directly into the browser console, I can successfully display capitalized text in bold.

Could it be something specific to shiny causing the code to malfunction? It seems like the code needs to execute after the GT table is created, hence the null error message. How can I ensure the correct sequence of events in shiny?

Just for your information, I've attempted to wrap the strings in df$name with HTML tags, but it doesn't render correctly. For example, the following approach did not work:

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

Any guidance or assistance would be greatly appreciated. Below is a snippet of my code.

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)

Answer №1

One approach is to postpone the execution of the JavaScript code using setTimeout, such as waiting for 2 seconds:

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

The ideal delay value can be ambiguous. Another option is to utilize an interval that runs every 100 milliseconds until it locates the element:

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);

This piece of JavaScript code needs special attention when dealing with string handling, specifically doubling backslashes in regular expressions like so: /(\\b[A-Z]{2,}\\b)/g.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the technique for toggling a slide on a pseudo element?

Take a look at this jsfiddle link. I noticed that when you click the menu button, the little triangle pointing to the button only appears after the animation is complete. I would like the animation to start with the pseudo element and then show the drop-me ...

Tips for avoiding issues with double quotes when working with JavaScript and JSON

Creating a specific String format in JavaScript for JSON might be tricky. The goal is to generate a string like this: ["PNG","350x150","127 KB"] Here's the code snippet using string variables: var imgType = getImageType(); // Returns "PNG" var im ...

When manipulating an array in JavaScript, the final count is wrong and there is an unexpected object

When I click this button, the addToCart function is invoked which dispatches an action to the reducer to add an item to the cart. The goal is to store only one instance of a specific item and increment the amount if the same item is added again. case &apo ...

Unexpected behavior: Axios post still enters catch block despite successful completion of Rest API call

Having an issue with my axios post request not returning the value from the API in a non-success scenario (401 error). It works fine for successful scenarios. When using Postman to test the output of my reset password API by providing an incorrect current ...

Guide on organizing json object by various elements with distinct sorting patterns

Below is a JSON Object that needs to be sorted based on different conditions: var data1 = [ {id: "1", name: "b", lastname: "y", marks: "10"}, {id: "1", name: "a", lastname: "x", marks: "20"}, {id: "2", name: "a", lastname: "x", marks: "30" ...

storing HTML elements in Chrome's cache

I have developed a content uploading module that utilizes the file API. The HTML code is <input type="file" id="filepicker-input" multiple="true" style="display:none;"/> <div class="addfile_btndiv" id="addfile_btndiv"> ...

What is the quickest method for cycling through the most ancient elements in a collection? (Efficient way to execute a queue)

See edit too I'm currently working in JavaScript, but I believe any readable pseudocode may be able to help answer my question. Describing my issue might be a bit of a challenge, so feel free to ask for clarifications. I'll respond promptly and ...

Splidejs Integration in Nuxt.js with Vue

Is there anyone out there who has attempted to integrate a Vue solution into Nuxt as a plugin or module? I've been facing numerous challenges while trying to accomplish this correctly! My current struggle involves importing the Splide Vue slider fro ...

Strategies for enhancing jQuery performance using the find() method

I have a form with an id="test", consisting of various select, input, and textarea fields. My goal is to iterate through each field, check if it's empty, and perform an action accordingly. var editTest= $('#test'); editGeneric(editTest); ...

Enhancing the Like Button Functionality Upon Click

I recently created a Like button and it appears to be functioning correctly. However, I have encountered an issue when attempting to update the button text from "Like" to "Liked" without needing to refresh the entire page. The problem is that every single ...

Guide on injecting javascript code containing php variables into a php page

I have successfully developed a PHP page and Javascript code that includes some PHP variables. The code is designed to insert PHP variables into the database using Javascript: <?php $id = "Kevin"; $user = "Calvin"; ?> <!-- include jquer ...

Utilizing Google's GeoApi to retrieve users' location data regarding their city and country

I am currently using this code to retrieve the full address information of users function getGeo() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (a) { $("#geoLoc").html("Determining your location. ...

Building intricate hierarchical menus with Material-UI 4.9

I am currently incorporating the @material-ui/core library into my application and aiming to implement a nested menu feature. I have referred to the material.io specification which discusses nested menus, but unfortunately, the material-ui library does not ...

Calculation of the ROC curve's area using a large dataset in the ff format

Greetings! I am currently utilizing various R libraries: library(pROC) library(ff) library(ffbase) library(biglm) Using the code below, I am attempting to build a logistic regression model with a large data frame (ffdf) and calculate the area under the R ...

Distinguish between Arrays and Objects in JavaScript

My AJAX request is fetching a JSON formatted response which could be in the form of an object like this: { name: "gideon", class: "knight", ... } or an array of objects like this: [ { name: "gideon", class: "knight", ...

Assign an array value to the input based on the selection made in Javascript

After finding a lot of useful information in previous questions, I am struggling to get the last piece that I need. My PHP code helps me loop through form fields and assign unique names to each field using a variable. One of these fields is for "expense ty ...

Achieving left alignment for Material-UI Radio buttons: Float them left

Click here to view the demo https://i.stack.imgur.com/Yt4ya.png Check out the demo above to see the code in action. I'm currently struggling to align the radio buttons horizontally, wondering if there's an easier way to achieve this using Mater ...

Update the input field value dynamically using jQuery upon creation

Is there a more efficient way to change the value of an input field when it's dynamically created using jQuery? For example, when clicking on an "Add" button, a new element appears and triggers a GET call resulting in the following HTML code: <tr ...

Exchanging items through Drag and Drop

My current project involves using drag and drop functionality to allow students to rearrange pieces of an image that has been jumbled up. They can drag these pieces onto a grid to recreate the original image. Both the jumbled up grid and the reconstructio ...

You are unable to define a module within an NgModule since it is not included in the current Angular compilation

Something strange is happening here as I am encountering an error message stating 'Cannot declare 'FormsModule' in an NgModule as it's not a part of the current compilation' when trying to import 'FormsModule' and 'R ...