6PO0222
6PO0222

Reputation: 131

JavaScript function not working in shiny.semantic module (but no error)

Following this thread and this one (both working), I am trying to implement a 'select all' button in a shiny.semantic::multiple_checkbox widget called from a module using update_multiple_checkbox.

Following this approach for running a custom JavaScript in a Shiny module from a file, my following code does not work but does not trigger any error in the browser console neither.

I also included a function to control that Shiny reads the JS file properly, which is the case.

Finally, extracting the HTML code from the browser and including it in a JSFiddle with the JS code works as well.

Any idea where I could be mistaken?

App & Module

library(shiny)
library(shiny.semantic)
library(shinyjs)
library(glue)


### MODULE ui ###
checkModule_ui <- function(id) {
    ns <- NS(id)
    
    multiple_checkbox(input_id = ns("myCheckbox"),
                      label = NULL,
                      choices = "")
}

### MODULE server ###
checkModule_server <- function(id){
    ns <- NS(id)
    
    moduleServer(id, function(input, output, session){
        update_multiple_checkbox(session = session,
                                 input_id = "myCheckbox",
                                 choices = c("All", "A", "B"),
                                 selected = c("All", "A", "B"))
        
        shinyjs::runjs(glue("checkModuleJSFunction('{ns(\"\")}', 'myCheckbox');"))
        
        #Control that Shiny sees the JS file and the selector
        shinyjs::runjs(glue("control_JS('{ns(\"\")}', 'myCheckbox');"))
    })
}

### APP ui ###
ui <- semanticPage(
    suppressDependencies("bootstrap"),
    useShinyjs(),
    
    tags$head(
        tags$script(src = "checkModuleJS.js")
    ),
    
    checkModule_ui(id = "moduleID")
)

### APP server ###
server <- function(input, output, session) {
    checkModule_server(id = "moduleID")
}

shinyApp(ui, server)

www/checkModuleJS.js

function checkModuleJSFunction(ns, id) {
    $("#" + ns + id + " input[value='All']").removeClass("hidden");
    
    $("#" + ns + id + " input[value='All']").click(function(e) {
        $("#" + ns + id + " input[type='checkbox']").prop('checked', $(e.target).prop("checked"));
    });
}

/* Control that Shiny sees this JS file and the selector*/
function control_JS(ns, id) {
    console.log("#" + ns + id + " input[value='All']");
}

sessionInfo()

R version 3.6.3
shiny_1.5.0
shiny.semantic_0.4.3
shinyjs_2.0.0.9000
glue_1.4.2

Upvotes: 1

Views: 331

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

This works with this code:

function checkModuleJSFunction(ns, id) {
  id = "#" + ns + id;
  $("body") 
    .on("click", id + " > div:nth-child(2) > div", function (e) {
      var allIsChecked = $(id + " input[value='All']").prop("checked");
      $(id + " .ui.checkbox" + " input[value!='All']")
        .prop("checked", allIsChecked);
    });
}

The point is that this is not by clicking on an input element that checks/unchecks the checkbox, but on the div element which contains the input.

Upvotes: 1

Related Questions