-
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