- Notifications
You must be signed in to change notification settings - Fork 1.9k
Closed
Description
Consider a basic input binding:
# app.R library(shiny) incrementButton <- function(inputId, value = 0) { tagList( tags$head(tags$script(src = "increment.js")), tags$button(id = inputId, class = "increment btn btn-default", type = "button", as.character(value)) ) } ui <- fluidPage( incrementButton("foo"), textOutput("foo_value") ) server <- function(input, output, session) { output$foo_value <- renderText({ paste("Clicked this many times:", input$foo) }) } shinyApp(ui, server)// www/increment.js $(document).on("click", "button.increment", function(evt) { // evt.target is the button that was clicked var el = $(evt.target); // Set the button's text to its current value plus 1 el.text(parseInt(el.text()) + 1); // Raise an event to signal that the value changed el.trigger("change"); }); var incrementBinding = new Shiny.InputBinding(); $.extend(incrementBinding, { find: function(scope) { return $(scope).find(".increment"); }, getValue: function(el) { return parseInt($(el).text()); }, setValue: function(el, value) { $(el).text(value); }, subscribe: function(el, callback) { $(el).on("change.incrementBinding", function(e) { callback(); }); }, unsubscribe: function(el) { $(el).off(".incrementBinding"); } });Now, if we register synchronously all is fine, but not if we register in a setTimeout(), the binding doesn't bind to the DOM:
setTimeout(() => { Shiny.inputBindings.register(incrementBinding); }, 100);That use case may seem contrived, but becomes a real problem if you're trying to load JS dependencies asynchronously (e.g., via requirejs) to define/register the binding:
incrementButton <- function(inputId, value = 0) { tagList( tags$head( tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" tags$script(src = "increment.js") ), tags$button(id = inputId, class = "increment btn btn-default", type = "button", as.character(value)) ) }require.config({paths: {"lodash": "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min"}}); require(["lodash"], function(_) { const finalBinding = _.last([incrementBinding]); Shiny.inputBindings.register(finalBinding); })Metadata
Metadata
Assignees
Labels
No labels