[rstudio::conf(2020L)] Bringing JavaScript to Shiny with {golem}

Db8efd836c9a09b71e3d8e1c60d6ea84?s=47 Colin Fay
January 28, 2020

[rstudio::conf(2020L)] Bringing JavaScript to Shiny with {golem}

Short talk given during "JavaScript for Shiny Users" workshop at rstudio::conf(2020)

Related project:

https://github.com/ColinFay/shinynotifyjs

https://github.com/ColinFay/notifyjsexample

Db8efd836c9a09b71e3d8e1c60d6ea84?s=128

Colin Fay

January 28, 2020
Tweet

Transcript

  1. Bringing JavaScript to Shiny with {golem} Colin Fay - ThinkR

    Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 1 / 26
  2. $ whoami Colin FAY Data Scientist & R-Hacker at ThinkR,

    a french company focused on Data Science & R. Hyperactive open source developer. http://thinkr.fr http://rtask.thinkr.fr http://twitter.com/_colinfay http://github.com/colinfay Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 2 / 26
  3. ThinkR Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 3 / 26

  4. Data Science engineering, focused on R. Training Software Engineering R

    in production Consulting ThinkR Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 4 / 26
  5. {golem} {golem} is an R package that contains a framework

    for building production-ready Shiny Applications. Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 5 / 26
  6. Why {golem}? Who can write this from memory? $( document

    ).ready(function() { Shiny.addCustomMessageHandler('fun', function(arg) { }) }); Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 6 / 26
  7. Why {golem}? Who can write this from memory? $( document

    ).ready(function() { Shiny.addCustomMessageHandler('fun', function(arg) { }) }); And insert it in your app? Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 6 / 26
  8. Why {golem}? Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 7 / 26

  9. {golem} & JavaScript Don't think about writing skeleton Don't think

    about integrating scripts Built-in functions Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 8 / 26
  10. Calling JS funs Don't think about writing skeleton golem::add_js_handler("handlers") $(

    document ).ready(function() { Shiny.addCustomMessageHandler('fun', function(arg) { }) }); Call them from the server with session$sendCustomMessage("fun", arg) Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 9 / 26
  11. Calling JS funs Good practice $( document ).ready(function() { Shiny.addCustomMessageHandler('fun',

    function(arg) { arg.this + arg.that }) }); Call them with session$sendCustomMessage( "fun", list( this = 40, that = 42 ) ) Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 10 / 26
  12. Why {golem}? Don't think about integrating scripts golem::add_js_handler("handlers", "~/golex", open

    = FALSE) ✓ File created at /Users/colin/golex/inst/app/www/handlers.js • To link to this file, go to the `golem_add_external_resources()` function in `app_ui.R` and add `tags$script(src="www/handlers.js")` • Go to /Users/colin/golex/inst/app/www/handlers.js Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 11 / 26
  13. Built-in functions golem_add_external_resources <- function(){ addResourcePath( 'www', system.file('app/www', package =

    'plplplplplplp') ) tags$head( golem::activate_js(), golem::favicon() # Add here all the external resources # If you have a custom.css in the inst/app/www # Or for example, you can add shinyalert::useShinyalert() here #tags$link(rel="stylesheet", type="text/css", href="www/custom.css") ) } Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 12 / 26
  14. Built-in functions golem::activate_js() <script>$( document ).ready(function() { Shiny.addCustomMessageHandler('show', function(what) {

    $(what).show() }); Shiny.addCustomMessageHandler('hide', function(what) { $(what).hide() }); Shiny.addCustomMessageHandler('showid', function(what) { $("#" + what).show() }); Shiny.addCustomMessageHandler('hideid', function(what) { $("#" + what).hide() }); Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 13 / 26
  15. Built-in functions Don't reinvent the wheel show & hide showid

    & hideid clickon disable And more to come in golem 0.2.0 Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 14 / 26
  16. Calling built-in functions golem::invoke_js("fun", "selection") For example golem::invoke_js("clickon", "a[data-value ='geom_point']")

    Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 15 / 26
  17. Project time https://github.com/ColinFay/shinynotifyjs Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 16 /

    26
  18. notify.js notifyjs is an open source JavaScript library designed to

    create custom notification boxes, released under the MIT License. https://notifyjs.jpillora.com/ Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 17 / 26
  19. Our goal for today Bring notifyjs to Shiny Colin FAY

    (@_ColinFay) - https://rtask.thinkr.fr 18 / 26
  20. Create a {golem} app Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 19

    / 26
  21. Download notifyjs in the app Should go into app/inst/www Colin

    FAY (@_ColinFay) - https://rtask.thinkr.fr 20 / 26
  22. Download notifyjs in the app Should go into app/inst/www download.file(

    "https://rawgit.com/notifyjs/notifyjs/master/dist/notify.js", "inst/app/www/notify.js" ) Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 20 / 26
  23. Add to your app In R/app_ui.R, in golem_add_external_resources() Use a

    tags$script or create an htmlDependency Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 21 / 26
  24. Add to your app In R/app_ui.R, in golem_add_external_resources() Use a

    tags$script or create an htmlDependency htmltools::htmlDependency( "notifyjs", version = "0.1.0", src = system.file('app/www', package = 'shinynotifyjs'), script = "notify.js" ) Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 21 / 26
  25. Try it Add an onclick event on a button Colin

    FAY (@_ColinFay) - https://rtask.thinkr.fr 22 / 26
  26. Try it Add an onclick event on a button actionButton(

    "plop", "plop", onclick = '$.notify("Hello World");' ) Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 22 / 26
  27. Create a custom handler Takes a text as input and

    show a success alert with the text in it Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 23 / 26
  28. Create a custom handler Takes a text as input and

    show a success alert with the text in it $( document ).ready(function() { Shiny.addCustomMessageHandler('notify', function(text) { $.notify(text); }) }); Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 23 / 26
  29. Create an R function That can call this custom handler

    from server side Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 24 / 26
  30. Create an R function That can call this custom handler

    from server side send_success <- function( text, session = shiny::getDefaultReactiveDomain() ){ session$sendCustomMessage("notify", text) } Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 24 / 26
  31. pop_success(text) pop_error(text) pop_info(text) pop_warn(text) pop_success(text, position) pop_error(text, position) pop_info(text, position)

    pop_warn(text, position) pop_success(text, autoHide) pop_error(text, duration) pop_info(text, clickToHide) Create more custom alerts Use the notifyjs options See "Custom Styling Guide" at https://notifyjs.jpillora.com/ Ideas: Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 25 / 26
  32. Online colin@thinkr.fr http://twitter.com/_colinfay http://twitter.com/thinkr_fr https://github.com/ColinFay https://thinkr.fr/ https://rtask.thinkr.fr/ https://colinfay.me/ Related projects

    connect.thinkr.fr/engineering-shiny {shinipsum} {fakir} {shinysnippets} Thx! Questions? Colin Fay Colin FAY (@_ColinFay) - https://rtask.thinkr.fr 26 / 26