rshinyhtmltools

Why use tagQuery() in shiny apps?


I have read this article on tagQuery() and was left wondering what could be the practical use in a shiny app.

Is it to modify a tag on the server side in a way similar to shinyjs::addClass()?


Solution

  • I think it’s mostly useful when you need to modify or extract parts of a potentially deeply nested HTML structure. Such a need may arise in particular in cases where you don’t have control over creating the original structure, but rely on a package to do that for you.

    For a real example, this old answer of mine could benefit from using tagQuery().

    As the setup, we have a dynamically generated menu. There, we want to add an id attribute to the ul element inside, in order to be able to later target that element with JavaScript.

    library(shinydashboard, warn.conflicts = FALSE)
    library(htmltools)
    
    tabs_list <- lapply(1:2, function(x) {
      menuSubItem(text = paste("tab", x))
    })
    
    menu <- menuItem("test_tabs", tabs_list)
    print(menu)
    #> <li class="treeview">
    #>   <a href="#">
    #>     <span>test_tabs</span>
    #>     <i class="fa fa-angle-left pull-right" role="presentation" aria-label="angle-left icon"></i>
    #>   </a>
    #>   <ul class="treeview-menu" style="display: none;" data-expanded="test_tabs">
    #>     <li>
    #>       <a href="#">
    #>         <i class="fa fa-angle-double-right" role="presentation" aria-label="angle-double-right icon"></i>
    #>         tab 1
    #>       </a>
    #>     </li>
    #>     <li>
    #>       <a href="#">
    #>         <i class="fa fa-angle-double-right" role="presentation" aria-label="angle-double-right icon"></i>
    #>         tab 2
    #>       </a>
    #>     </li>
    #>   </ul>
    #> </li>
    

    Here’s the original approach:

    menu_orig <- menu
    menu_orig$children[[2]] <- tagAppendAttributes(menu_orig$children[[2]], id = "test_tabs")
    

    With tagQuery() this would be easier to understand and more robust:

    menu_tq <- tagQuery(menu)$find("ul")$addAttrs(id = "test_tabs")$allTags()
    
    # Check that we got the same result
    identical(format(menu_orig), format(menu_tq))
    #> [1] TRUE