Remove null values from html css tags in shiny

I have a simple shiny application where in when you click on the plus sign, the drop down appears.That is fine. (This is a rough table. Do not worry)

library(shiny)
library(DT)

ui <- fluidPage(
  dataTableOutput("ry")
)

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

  output$ry <- renderDataTable({
    
    
    callback <- paste0("
        table.column(1).nodes().to$().css({cursor: 'pointer'});
                                      var format = function(d) {
                                      return '<body><div style=\"background-color:#cbe6ef; padding: .5em;text-align:center;\"><table><tr><td><b>Tag</b></td><td><b>Number of Reviews</b></td><td><b> Share of Reviews </b></td><td><b> Click for Reviews </b></td> <tr><td> null </td><td>' + d[50] + '</td><td>' + d[51] + '</td><td>' + d[52] + '</td></tr> <tr><td>' + d[45] + '</td><td>' + d[46] + '</td><td>' + d[47] + '</td><td>' + d[48] + '</td></tr> <tr><td>' + d[41] +'</td></tr> </tr></table></div></body>';};
                                      table.on('click', 'td.details-control', function() {
                                      var td = $(this), row = table.row(td.closest('tr'));
                                      if (row.child.isShown()) {
                                      row.child.hide();
                                      td.html('&plus;');
                                      } else {
                                      row.child(format(row.data())).show();
                                      td.html('&minus;');
                                      }
                                      });")
    
    
    datatable(cbind(Plus = '&plus;',iris),
              escape = F,
              rownames = F,options = list(                  columnDefs = list(
                list(orderable = FALSE, className = 'details-control', targets = c(0))
              )),
              callback = JS(callback
              ))
  })
}

shinyApp(ui, server)

But as you can see there are null values here. So when there are null values , that entire row should get removed. So I tried with below stuffs but not working

library(shiny)
library(DT)

ui <- fluidPage(
  dataTableOutput("ry")
)

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

  output$ry <- renderDataTable({
    
    
    callback <- paste0("
        table.column(1).nodes().to$().css({cursor: 'pointer'});
                                      var format = function(d) {
                                      return '<body><div style=\"background-color:#cbe6ef; padding: .5em;text-align:center;\"><table><tr><td><b>Tag</b></td><td><b>Number of Reviews</b></td><td><b> Share of Reviews </b></td><td><b> Click for Reviews </b></td> <tr><td> null </td><td>' + d[50] + '</td><td>' + d[51] + '</td><td>' + d[52] + '</td></tr> <tr><td>' + d[45] + '</td><td>' + d[46] + '</td><td>' + d[47] + '</td><td>' + d[48] + '</td></tr> <tr><td>' + d[41] +'</td></tr> </tr></table></div><script type='text/javascript'> document.querySelectorAll('td').forEach((item) => {if (item.textContent.includes('null')) {item.parentElement.remove();}});</script></body>';};
                                      table.on('click', 'td.details-control', function() {
                                      var td = $(this), row = table.row(td.closest('tr'));
                                      if (row.child.isShown()) {
                                      row.child.hide();
                                      td.html('&plus;');
                                      } else {
                                      row.child(format(row.data())).show();
                                      td.html('&minus;');
                                      }
                                      });")
    
    
    datatable(cbind(Plus = '&plus;',iris),
              escape = F,
              rownames = F,options = list(                  columnDefs = list(
                list(orderable = FALSE, className = 'details-control', targets = c(0))
              )),
              callback = JS(callback
              ))
  })
}

shinyApp(ui, server)

Can anyone help me here please

Have you noticed that even where values are not null they are undefined, so there is basically no useful information anyway ?

Yeah I know. That was just a sample data. Undefined is fine. But when any of the value in rows are null, then entire row should removed. I tried with above approach (using javascript) but not working.

I dont study javascript, but I added javascript tag to your question.

I see. But is there another way to do this?:slight_smile: Without javascript? Just removing null rows

library(shiny)
library(DT)
library(tidyverse)
add_collapse_content <- function(x, id) {
  tagList(
    tags$button(
      "data-toggle" = "collapse",
      "data-target" = paste0("#", id),
      "+"
    ),
    div(
      "id" = id,
      "class" = "collapse",
      x
    )
  )
}

ui <- fluidPage(
  DTOutput("table")
)

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

  output$table <- renderDT({
    pciris <-
      iris %>%
      mutate(rn = row_number()) %>%
      rowwise() %>%
      mutate(
        plus_column =
          add_collapse_content(p(paste("some content",rn)),
            id = paste0("pc_", rn)
          ) %>%
            as.character()
      ) %>%
      relocate(plus_column)

    datatable(pciris,
      escape = F,
      rownames = F, options = list(columnDefs = list(
        list(orderable = FALSE, className = "details-control", targets = c(0))
      ))
    )
  })
}

shinyApp(ui, server)

Thanks. This is the best alternate. But I tried with small change (I put some html tags in my content), it is not rendering

library(shiny)
library(DT)
library(tidyverse)
add_collapse_content <- function(x, id) {
  tagList(
    tags$button(
      "data-toggle" = "collapse",
      "data-target" = paste0("#", id),
      "+"
    ),
    div(
      "id" = id,
      "class" = "collapse",
      x
    )
  )
}

ui <- fluidPage(
  DTOutput("table")
)

server <- function(input, output, session) {
  
  output$table <- renderDT({
    pciris <-
      iris %>%
      mutate(rn = row_number()) %>%
      rowwise() %>%
      mutate(
        plus_column =
          add_collapse_content(HTML("<body><div style=\"background-color:#cbe6ef; padding: .5em;text-align:center;\"><table><tr><td><b>Tag</b></td><td><b>Number of Reviews</b></td><td><b> Share of Reviews </b></td><td><b> Click for Reviews </b></td> <tr><td> null </td><td>' + d[50] + '</td><td>' + d[51] + '</td><td>' + d[52] + '</td></tr> <tr><td>' + d[45] + '</td><td>' + d[46] + '</td><td>' + d[47] + '</td><td>' + d[48] + '</td></tr></td></tr> </tr></table><script type='text/javascript'> document.querySelectorAll('td').forEach((item) => {if (item.textContent.includes('null')) {item.parentElement.remove();}})</script></body></div></body>"),
                               id = paste0("pc_", rn)
          ) %>%
          as.character()
      ) %>%
      relocate(plus_column)
    
    datatable(pciris,
              escape = F,
              rownames = F, options = list(columnDefs = list(
                list(orderable = FALSE, className = "details-control", targets = c(0))
              ))
    )
  })
}

shinyApp(ui, server)

I dont understand why you added the HTML tags that you did... They are not well formed.
There is one open body tag and two closing body tags for example.
And there should only be a single body tag for a page, I wouldnt expect it to be used in any subelements...
Also you've included javascript, that I thought you had been happy to dodge the need for ?
If you apply well formed HTML without inline javascript, I expect what we have set up to work, would work.