skip to Main Content

The orderInput() function from the shinyjqui package utilizes six pre-defined Bootstrap button classes to style the items it displays. These styles can be specified using the item_class parameter. For further details, refer to the documentation.

I try to add additional classes, the orderInput() function, that appears to be designed to only accept the six predefined Bootstrap button classes (default, primary, success, info, warning, danger).

I this possible?

library(shiny)
library(shinyjqui)

ui <- fluidPage(
  tags$head(
    tags$style(
      HTML("
            .grey { background-color: grey; color: white; }
           ")
    )
  ),
  
  uiOutput("custom_orderInput")
)

server <- function(input, output, session) {
  
  output$custom_orderInput <- renderUI({
    
    tagList(
      orderInput('default', 'default', items = 1:3, item_class = 'default'),
      orderInput('primary', 'primary', items = 1:3, item_class = 'primary'),
      orderInput('success', 'success', items = 1:3, item_class = 'success'),
      orderInput('info', 'info', items = 1:3, item_class = 'info'),
      orderInput('warning', 'warning', items = 1:3, item_class = 'warning'),
      orderInput('danger', 'danger', items = 1:3, item_class = 'danger'),
      orderInput('grey', 'grey', items = 7:9, item_class = 'grey')
    )
    
  })
  
}

shinyApp(ui, server)

2

Answers


  1. Update: Implemented the suggestion by @Stéphane Laurent:

    changed .grey > button with #grey > .btn
    removed library(shinyjs) and useShinyjs()
    and increase 50 to 75

    The orderInput() function from shinyjqui is designed with Bootstrap button classes in mind. If the function doesn’t natively support custom classes, you might need to apply a hack to get around this.

    You have defined the .grey class correctly, but if orderInput() isn’t directly supporting custom classes, one method would be to use JavaScript to modify the class attribute of the rendered HTML elements after they’ve been created by Shiny.

    Perhaps you could try this workaround to fix your issue:

    Include a shinyjs function to run custom JS.
    Run a small JS script to add your custom class to the desired elements after they’re rendered. Now you can modify your existing code to achieve this:

    library(shiny)
    library(shinyjqui)
    
    ui <- fluidPage(
      tags$head(
        tags$style(
          HTML("
                .grey { background-color: grey; color: white; }
               ")
        )
      ),
      
      uiOutput("custom_orderInput"),
      
      # Add a JS script to add the 'grey' class to the appropriate elements
      tags$script(
        HTML("
             $(document).on('shiny:connected', function(event) {
               setTimeout(function(){
                 $('#grey > .btn').addClass('grey');
               }, 75);
             });
             ")
      )
    )
    
    server <- function(input, output, session) {
      
      output$custom_orderInput <- renderUI({
        
        tagList(
          orderInput('default', 'default', items = 1:3, item_class = 'default'),
          orderInput('primary', 'primary', items = 1:3, item_class = 'primary'),
          orderInput('success', 'success', items = 1:3, item_class = 'success'),
          orderInput('info', 'info', items = 1:3, item_class = 'info'),
          orderInput('warning', 'warning', items = 1:3, item_class = 'warning'),
          orderInput('danger', 'danger', items = 1:3, item_class = 'danger'),
          orderInput('grey', 'grey', items = 7:9, item_class = 'default') # Use 'default' as a placeholder
        )
        
      })
      
    }
    
    shinyApp(ui, server)
    

    This way utilizing the shinyjs package to integrate custom JS. After the Shiny app connects, the JavaScript waits for a short time (50ms in this case, but you can adjust as needed) and then adds the .grey class to the button elements inside the .grey parent. We also set the item_class to ‘default’ as a placeholder, which will be overridden by our JS.

    Login or Signup to reply.
  2. @0xe1λ7r’s answer is nice. That said, you can avoid the use of setTimeout which implies a choice of the delay, and use setInterval and clearInterval instead:

        HTML("
             $(document).on('shiny:connected', function(event) {
                var interval = setInterval(function() {
                  var $itemGroup = $('#grey > .btn');
                  if($itemGroup.length) {
                    $itemGroup.addClass('grey');
                    clearInterval(interval);
                  }
                }, 10);
             });
       ")
    

    With this code, the existence of the items group is checked each period of 10 ms after the Shiny connection, and once it is detected the new class is added and then the code is destroyed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search