Search code examples
shinyshiny-servershinyjs

Shinyjs cant enable/disable UI element properly


I have below Shiny app

library(shiny)
runApp(shinyApp(
    ui = fluidPage(
        shinyjs::useShinyjs(),
       selectizeInput(inputId = "aaa", label = NULL, choices = c('a', 'b', 'c', 'd', 'e', 'f'), selected = NULL, width = '90%',
                         options = list(placeholder = 'Get', 
                                                onInitialize = I('function() { this.setValue(""); }'), maxItems = 5)),
       radioButtons("bbb", label = NULL, inline = TRUE, width = "100%", selected = 95,
                                                        choiceValues = list(1, 2, 3),
                                                        choiceNames = list(
                                                                            div(style = "font-size:24px;", "1%"), 
                                                                            div(style = "font-size:24px;", "2%"), 
                                                                            div(style = "font-size:24px;", "3%")
                                                                          ))
    ),
    server = function(input, output, session) {
        observeEvent(input$aaa, {
            if(grepl("a", input$aaa)){
                shinyjs::enable("bbb")
            }else{
                shinyjs::disable("bbb")
            }
        })
    }
))

When I select a, b, c, I get Radiobutton enabled, Now then if I remove all my selections then still I see that enabled. This is strange to me because I would expect that would be disabled. Then after removing all, if I make a fresh selection without a then still it remains enabled.

Can somebody show me any pointer what went wrong?


Solution

  • I made two changes and it's working almost as you want : - Initialize the radiobuttons as disabled - Pass only one true/false to the if

    library(shiny)
    library(shinyjs)
    runApp(shinyApp(
      ui = fluidPage(
        shinyjs::useShinyjs(),
        selectizeInput(inputId = "aaa", label = NULL, choices = c('a', 'b', 'c', 'd', 'e', 'f'), selected = NULL, width = '90%',
                       options = list(placeholder = 'Get', 
                                      onInitialize = I('function() { this.setValue(""); }'), maxItems = 5)),
        shinyjs::disabled( # buttons disable at the launching
          radioButtons("bbb", label = NULL, inline = TRUE, width = "100%", selected = 95,
                       choiceValues = list(1, 2, 3),
                       choiceNames = list(
                         div(style = "font-size:24px;", "1%"), 
                         div(style = "font-size:24px;", "2%"), 
                         div(style = "font-size:24px;", "3%")
                       ))
        )
    
      ),
      server = function(input, output, session) {
        observeEvent(input$aaa, {
          # any(grepl(...)) returns TRUE if one of them is TRUE
          # just grepl(..) would return a vector of TRUE and FALSE
          if(any(grepl("a", input$aaa))){
            shinyjs::enable("bbb")
          }else{
            shinyjs::disable("bbb")
          }
        })
      }
    ))
    

    I don't know why the buttons keeps being enabled when nothing is selected after having selected a "a"

    EDIT : it looks like observeEvent doesn't react when an input has a value then is NULL. Using observe() instead solves the problem.

    library(shiny)
    library(shinyjs)
    runApp(shinyApp(
      ui = fluidPage(
        shinyjs::useShinyjs(),
        selectizeInput(inputId = "aaa", label = NULL, choices = c('a', 'b', 'c', 'd', 'e', 'f'), selected = NULL, width = '90%',
                       options = list(placeholder = 'Get', 
                                      onInitialize = I('function() { this.setValue(""); }'), maxItems = 5)),
        shinyjs::disabled(
          radioButtons("bbb", label = NULL, inline = TRUE, width = "100%", selected = 95,
                       choiceValues = list(1, 2, 3),
                       choiceNames = list(
                         div(style = "font-size:24px;", "1%"), 
                         div(style = "font-size:24px;", "2%"), 
                         div(style = "font-size:24px;", "3%")
                       ))
        )
    
      ),
      server = function(input, output, session) {
    
        observe({
            if(any(grepl("a", input$aaa))){
              shinyjs::enable("bbb")
            }else{
              shinyjs::disable("bbb")
            }
          }
        )
      }
    ))