Skip to content
dcruvolo edited this page May 21, 2020 · 15 revisions

On this page, you can find more information about the functions included in the browsertools package.

Contents

Quick Reference

The functions and their arguments and descriptions included in the browsertools are listed in the following table. Click on a function name for more information and examples.

function arguments description
use_browsertools --- loads the browsertool dependencies into your shiny app (required)
debug --- prints JavaScript errors in the R Console
add_css elem, css add a css class to an element
as_js_object x a data.frame to convert to javascript object
console_error message send an error message to the console
console_log message display a message or data in the console
console_table data a json object to display in the console; use as_js_object function to convert your data before passing into the function
console_warn message display warning message in the console
hide_elem elem, css hides an element by adding a class by name or hidden
insert_adjacent_html id, html, position add an html element(s) to a parent element
inner_html elem, string, delay write values to an element.
refresh_page --- trigger a page refresh (history.go(0))
remove_css elem, css remove a css class from an element
remove_element elem remove an element from the DOM
remove_element_attribute elem, attr remove an attribute from an element
set_element_attribute elem, attr, value update an attribute of an element
scroll_to_top --- scroll to top of page
show_elem elem, css show an element by removing a class name or hidden
toggle_css elem, css toggle a css class

Concepts

Selecting Elements

Many of these function uses js's querySelector to for selecting elements (ie., input argument elem). You can you select html elements in a number of ways: ID selectors (e.g., "#myelem"), class selectors (e.g.,some-element), type selectors (e.g., select), attribute selectors (e.g., input[name="some-input-name"]), combinators (e.g., :first-child), etc.. This function will only select the first element using the selector path. See Mozilla's CSS Selectors guide for more information.

Here are a few examples of using the function toggle_css using different selector types. Let's say there is a block style called blue-text.

library(shiny)
library(browsertools)

# ui.R
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".blue {color: blue;}",
            ".error {color: red;}",
            ".link {font-weight: bold; font-size: 16pt;}",
            ".italic {font-style: italic; }",
            ".upper {text-transform: uppercase;}"
        )
    ),
    tags$h1("Selecting Elements Examples"),
    # normal text
    tags$p("This is normal text. Select the button below to apply styles"),

    # blue text using ID selector
    tags$p(
        id = "myelem",
        "I am styled using an ID selector"
    ),

    # red text selected by class name
    tags$p(
        class = "error-message",
        "Let's pretend this is an error message styled using a class selector"
    ),

    # normal text with link selector example
    tags$p(
        "See Mozilla's",
        tags$a(
            href = "https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors",
            "CSS Selector"
        ),
        "guide for more examples and information (the link is styled bold)"
    ),

    # attribute selector
    tags$p(
        `data-value` = "12345",
        "I am styled using an attribute selector"
    ),

    # pseudo elements
    tags$p(
        "this element is styled using pseudo elements"
    ),

    # button
    tags$button(
        id = "btn",
        class = "shiny-bound-input action-button",
        "Toggle Styles"
    )

)

server <- function(input, output, session) {
    observeEvent(input$btn, {
        # ID selector
        toggle_css(elem = "#myelem", css = "blue")

        # Class Selector
        toggle_css(elem = ".error-message", css = "error")

        # Type selector
        toggle_css(elem = "a", css = "link")

        # Attribute Selectors (type + attribute)
        toggle_css(elem = "p[data-value='12345']", css = "italic")

        # Combinator Selector
        toggle_css(elem = "p:last-of-type", css = "upper")
    })
}

# app
shinyApp(ui, server)

Function Reference

The following section provides more information about each function, as well as examples. All functions are written in vanilla javascript. The js code is optimized for use in development or production applications (~2kb). Babel is used to transpile and minify js code.

use_browsertools

Calling the use_browsertools function loads the package's dependencies into your application. This is required for using any function in your app.

Use

This function has no input arguments

Examples

In the shiny UI, call the function at the beginning.

library(shiny)

# ui.R
ui <- tagList(
    browsertools::use_browsertools(),
    ...
)

# server.R
server <- function(input, output, session) {

}

# app
shinyApp(ui, server)

debug

debug can be used for printing JavaScript errors in the R console. This may be useful if you are developing Shiny applications without a browser (i.e., in the view pane), using RStudio Cloud, or using your preferred dev environment.

Use

This function takes no arguments

Examples

The example below demonstrates how to see JS errors in the R console. Click the button to see the errors.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h2("Example Application using Debug"),
        tags$p("Click the button below to view a hidden message"),
        tags$button(
            id = "toggle",
            class = "shiny-bound-input action-button",
            "Toggle Message"
        ),
        tags$p(id = "txt", class = "visible", "Hello, world!")
    )
)


# server
server <- function(input, output, session) {
    browsertools::debug()
    observeEvent(input$toggle, {
        browsertools::toggle_css("txt", "visible")
    })
}

# app
shinyApp(ui, server)

add_css

The function add_css adds a css classname to an element by ID or class. This may be useful if you want to manipulate the client based on user interaction.

Use

This function takes the following arguments

  • elem: the selector of an html element that you wish to modify
  • css: the css classname that you wish to add

Examples

The following example demonstrates how to add a class to an element when a button is clicked.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".large-blue-text {",
            "color: blue;",
            "font-size: 32pt;",
            "}"
        )
    ),
    tags$main(
        tags$h1("Hello world!"),
        tags$p(
            id = "txt",
            "Click the button below to add styling to this sentence."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Add Styling"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::add_css(elem = "#txt", css = "large-blue-text")
    })
}

# app
shinyApp(ui, server)

as_js_object

The as_js_object function is useful for transforming R objects to javascript arrays and objects. This is important for linking Shiny and JavaScript libraries. You will need to define a custom handler in order to use it in js.

Use

This function has one input argument.

  • x: an array or data.frame to convert

Example

d <- browsertools::as_js_object(iris[1:5, ])
print(d)
# 
# [[1]]
# [[1]]$Sepal.Length
# [1] 5.1
# 
# [[1]]$Sepal.Width
# [1] 3.5
# 
# [[1]]$Petal.Length
# [1] 1.4
# 
# [[1]]$Petal.Width
# [1] 0.2
# 
# [[1]]$Species
# [1] setosa
# Levels: setosa versicolor virginica
# ...

console_error

console_error allows you to log an error message to the browser's console. This can help for sending messages for debugging production applications.

Use

This function takes the following arguments.

  • message: an error message to display

Examples

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("console_error example"),
        tags$p(
            id = "txt",
            "Open the dev console, and then click the button."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Send Message"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::console_error(message = "Something went wrong when you clicked the button")
    })
}

# app
shinyApp(ui, server)

console_log

console_log allows you to send string, value, or object to the browser's console. This is ideal for debugging shiny apps or printing helpful error messages in production applications.

Use

This function has one input argument.

  • message: an R object to send to the browser console (i.e., value, string, array, etc.).

If you would like to display a data.frame in the console, I would recommend using as_js_object and console_table

Examples

Use this function in the shiny server as written in the following examples.

# in server.R
console_log(message = "Hello, Browser! I am sent from the shiny server.")

The following example shows how to use this function using based on client interaction.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("console_log example"),
        tags$p(
            id = "txt",
            "Open the dev console, and then click the button below to print as message to the console."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Send Message"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::console_log(message = "hello, world!")
    })
}

# app
shinyApp(ui, server)

console_table

The console_table function is useful for printing data in the js console in table format. This may be useful for debugging or providing helpful error messages in production apps.

Use

This function takes one argument.

  • data: a converted R object into JS format

To send data to the console. Use the function as_js_object to transform data into a javascript object. (See examples)

Examples

Convert data before sending using console_table.

df <- as_js_object(x = iris[1:5, ])
console_table(data = df)

The following example demonstates how to send data to the console when a button is clicked.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("console_table example"),
        tags$p(
            id = "txt",
            "Click the button below to print a table in the console"
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Go!"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {

        # convert data
        d <- browsertools::as_js_object(iris[1:5, ])

        # send to console
        browsertools::console_table(data = d)
        
    })
}

# app
shinyApp(ui, server)

console_warn

Use console_warn to display a warning message in the browser's console.

Use

This function takes the following arguments

  • message: a warning message to display

Examples

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("console_warn example"),
        tags$p(
            id = "txt",
            "Open the dev console, and then click the button."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Send Message"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::console_warn(message = "This is to notify you that something will happen when the button is clicked")
    })
}

# app
shinyApp(ui, server)

hide_elem

hide_elem can be used for hidden an element in your shiny UI. This function works be removing a css class rather than modifying display properties as this approach is not always web accessible friendly. In a separate css file or in at the top of the app, define a css class name with hidden.

Use

This function takes the following arguments.

  • elem: an element to hide; use an ID, class, type selector, etc.
  • css: the name of the class used to hide elements (default: .browsertools-hidden; included in package)

Examples

To visually hide an element, the function hide_elem adds the following css class to the target element.

.browsertools-hidden {
    position: absolute;
    clip: rect(0, 0, 0, 0);
    clip: rect(0 0 0 0);
    width: 1px;
    height: 1px;
    overflow: hidden;
}

For good accessibility practices, I strongly recommend using the attribute aria-hidden and modifying this attribute using the function set_element_attribute.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".msg {",
            "color: red;",
            "}"
        )
    ),
    tags$main(
        tags$h1("show_elem example"),
        tags$p("Click the button to reveal a secret message"),
        tags$p(
            id = "secret",
            class = "msg",
            `aria-hidden` = "false",
            "Oh, no! The secret message is visible. Click the button to hide it."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Hide Message"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::hide_elem(elem = "#secret")
        browsertools::set_element_attribute(
            elem = "#secret",
            attr = "aria-hidden",
            value = "true"
        )
    })
}

# app
shinyApp(ui, server)

insert_adjacent_html

Render shiny tags an html string into the document.

Use

This function takes the following arguments

  • id: an id of a parent element (i.e., container) to render new elements into
  • html: html content to add to the document. Can be shiny tags object, html tags, or an html string
  • position: specify where in the output container you want to the render the new elements into (i.e., beforebegin, afterbegin, beforeend, afterend)*

*Note: See Mozilla's insertAdjacementHTML documentation for more information on positions

Examples

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(id = "main",
        tags$h1("insert_adjacent_html example"),
        tags$p("Click the button to add a new", tags$code("<p>"), "tag."),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Add Button"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::insert_adjacent_html(
            id = "main",
            html = tags$p("Hello, world! I'm a new message")
        )
    })
}

# app
shinyApp(ui, server)

inner_html

inner_html allows you to modify the internal content of an element.

Use

This function takes the following input arguments

  • elem: a selector path of the element you wish to modify
  • string: a character string containing the text or html to insert
  • delay: add a pause before the function is run (in milliseconds). This is useful for content rendered server side.

Examples

The following example provides an example using the inner_html function with server-side rendered content.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("inner_html example"),
        tags$p("Send a message to a server-side rendered UI element."),
        tags$form(
            tags$label(
                `for` = "msg",
                "Enter a message"
            ),
            tags$input(
                id = "msg",
                class = "shiny-bound-input",
                type = "text"
            ),
            tags$button(
                id = "btn",
                class = "action-button shiny-bound-input",
                "Hide Message"
            )
        ),
        uiOutput("message")
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        output$message <- renderUI({
            tags$section(
                tags$h2("Here is your message"),
                tags$p(id = "user-message")
            )
        })
        browsertools::inner_html(
            elem = "#user-message",
            string = input$msg,
            delay = 50
        )
    })
}

# app
shinyApp(ui, server)

refresh_page

refresh_page will trigger a page refresh.

Use

This function takes no input arguments

Examples

The following example shows how to refresh a page when a button is clicked.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("refresh_page example"),
        tags$p("Click the button to refresh the app"),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Go"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::refresh_page()
    })
}

# app
shinyApp(ui, server)

remove_css

This function removes a css class from an element by ID or classname

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".large-blue-text {",
            "color: blue;",
            "font-size: 32pt;",
            "}"
        )
    ),
    tags$main(
        tags$h1("Hello world!"),
        tags$p(
            id = "txt",
            class = "large-blue-text",
            "Click the button below to remove styling from the text."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Remove Text"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::remove_css(elem = "#txt", css = "large-blue-text")
    })
}

# app
shinyApp(ui, server)

remove_element

Remove an element from the page using an ID or classname.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("Hello world!"),
        tags$p(
            id = "txt",
            "Click the button below to remove this text."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Remove Text"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::remove_element(elem = "#txt")
    })
}

# app
shinyApp(ui, server)

remove_element_attribute

The remove_element_attribute allows you to modify the attributes of a specific element. This is useful for creating functional components.

Use

This function takes the following arguments

  • elem: a selector for an html element (ID, class, type, etc.)
  • attr: the name of the attribute you would like to remove

Examples

The following example shows how to remove an ID from an HTML element.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".blue{color:blue;}"
        )
    ),
    tags$main(
        tags$h1("remove_element_attribute example"),
        tags$p(
            id = "txt",
            class = "blue",
            "Click the button to remove this element's class (use inspect element)"
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Go"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::remove_element_attribute(
            elem = "#txt",
            attr = "class"
        )
    })
}

# app
shinyApp(ui, server)

NOTE: This example is for demonstration purposes only. Use remove_css for removing classes from an element.

scroll_to_top

This function resets the current view to the top of the page.

library(shiny)

# define a function that generates n paragraphs of lorem lipsum
lorem_lipsum <- function(n) {
    lorem <- stringi::stri_rand_lipsum(n)
    text <- list()
    lapply(seq_len(length(lorem)), function(index) {
        text[[index]] <<- shiny::tags$p(lorem[index])
    })
    return(shiny::tags$section(text))
}

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$main(
        tags$h1("scroll_to_top example"),
        lorem_lipsum(n = 20),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "To top of page"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::scroll_to_top()
    })
}

# app
shinyApp(ui, server)

set_element_attribute

set_element_attribute can used for modifying a attribute of an element from the shiny server. This is useful for building custom functional components.

Use

This function takes the following arguments.

  • elem: a selector for an html element (ID, class, type, etc.)
  • attr: the name of the attribute you would like to remove
  • value: the new value to assign to the selected attribute

Example

The following example shows how to update an attribute (data-value) when a button is clicked. Use inspect element to see the changes.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".blue{color:blue;}"
        )
    ),
    tags$main(
        tags$h1("refresh_page example"),
        tags$p(
            id = "txt",
            class = "blue",
            "Click the button to remove this element's class (use inspect element)"
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Go"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::set_element_attribute(
            elem = "#txt",
            attr = "data-value",
            value = "123456789"
        )
    })
}

# app
shinyApp(ui, server)

show_elem

show_elem can be used for showing a hidden element. This function worked by removing a css class rather than modifying display properties as this approach may not always be web accessible. In the css file assign a class name hidden and then add it in the list of classnames.

Use

This function takes the following arguments

  • elem: an element to show; enter an ID, class, type, etc.
  • css: the name of the class used to show hidden elements (default: .browsertools-hidden; included in package)

Examples

To visually show a hidden element, the function show_elem removes the following css class to the target element.

.browsertools-hidden {
    position: absolute;
    clip: rect(0, 0, 0, 0);
    clip: rect(0 0 0 0);
    width: 1px;
    height: 1px;
    overflow: hidden;
}

In the UI, add the class hidden to the element that you want to hide. For good accessibilty practices, I strongly recommend using the attribute aria-hidden as well.

tags$p(
    id = "message",
    class = "hidden",
    `aria-hidden` = "true",
    "Hello, World!"
)

Then in the shiny server, remove the class and modify the aria attribute (using the function set_element_attribute)

remove_css(elem = "#msg", class = "hidden")
set_element_attribute(elem = "#msg", attr = "aria-hidden", value = "false")

The following example demonstrates how to show a hidden element using a custom styles and aria attributes.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".msg {",
            "color: red;",
            "}"
        )
    ),
    tags$main(
        tags$h1("show_elem example"),
        tags$p("Click the button to reveal a secret message"),
        tags$p(
            id = "secret",
            class = "msg secret-message",
            `aria-hidden` = "true",
            "Oh, no! You found the secret message."
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Reveal"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::show_elem(elem = "#secret")
        browsertools::set_element_attribute(
            elem = "#secret",
            attr = "aria-hidden",
            value = "false"
        )
    })
}

# app
shinyApp(ui, server)

toggle_css

The toggle_css function will toggle a class of an element regardless of the current state (i.e., add or remove)

Use

This function takes the following arguments.

  • elem: the selector for the element you would like to modify (i.e., id, class, type selector, etc.)
  • css: the name of the class you want to toggle.

Examples

The following example demonstrates how to toggle a css class when a button is clicked.

library(shiny)

# ui
ui <- tagList(
    browsertools::use_browsertools(),
    tags$head(
        tags$style(
            ".large-blue-text {",
            "color: blue;",
            "font-size: 32pt;",
            "}"
        )
    ),
    tags$main(
        tags$h1("toggle_css example"),
        tags$p(
            id = "txt",
            "Click the button below to toggle the text styling"
        ),
        tags$button(
            id = "btn",
            class = "action-button shiny-bound-input",
            "Toggle Styles"
        )
    )
)

# server
server <- function(input, output, session) {
    observeEvent(input$btn, {
        browsertools::toggle_css(elem = "#txt", css = "large-blue-text")
    })
}

# app
shinyApp(ui, server)