Subscribe method not called in Shiny custom input binding

I'm trying to develop a custom input with Shiny by following this article.

The issue I found is that the subscribe method is not called after the custom input is initialized (that is, find and initializeare called but not subscribe). Here is a minimal example of what I'm trying to do:

app.R

library(shiny)

myModule = function(inputId, initialState) {
  tagList(
    shiny::singleton(tags$head(
      tags$script(src = 'js/binding.js')
    )),
    tags$div(
      tags$input(type = 'checkbox'),
      class = 'myModule'
    )
  )
}

ui <- fluidPage(
   fluidRow(
     column(12,
            myModule("myId", NULL))
   )
)

server <- function(input, output) {
   
}

# Run the application 
shinyApp(ui = ui, server = server)

And here is www/js/binding.js:

let binding = new Shiny.InputBinding();

$.extend(binding, {
  find: function(scope) {
    console.log('find called');
    return $(scope).find('.myModule');
  },

  initialize: function(el) {
    console.log('initialize called');
  },

  subscribe: function(el, callback) {
    console.log('subscribe called');
    $(el).find('input').change(callback);
  },

  getValue: function(el) {
    console.log('getValue called');
  },
});

Shiny.inputBindings.register(binding);

I know only find and initialize are called because these are the only messages that show up in the console when running the app.

If I understand correctly, to be able to talk to the server, the subscribe method is called by the Shiny JS library after the component is registered and the DOM is loaded. I don't know if I'm missing something or if this has to be manually triggered somehow. Any help would be greatly appreciated.

hi @elias, you probably forgot to set the id on the checkbox, with that it works.

library(shiny)

myModule = function(inputId, initialState) {
    tagList(
        shiny::singleton(tags$head(
            tags$script(src = 'js/binding.js')
        )),
        tags$div(
            tags$input(type = 'checkbox'), id = inputId,
            class = 'myModule'
        )
    )
}

ui <- fluidPage(
    fluidRow(
        column(12,
               myModule("myId", NULL))
    )
)

server <- function(input, output) {

}

# Run the application
shinyApp(ui = ui, server = server)
1 Like

Great! It's working now. Thanks for your quick response!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.