Wei
Wei

Reputation: 151

Greying out a section of a ShinyApp

I have an app where I wished to grey out whichever section that the user is not working on. When a particular section is greyed out, the user should not be able to modify anything in that section. I wonder if it is possible to add the "grey out" element to a shiny app?

Here is a MWE:

UI:

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  navbarPage(title = "Grey out", 
             tabPanel(title = "test", 
               column(width = 6, 
                      actionButton(inputId = "go", label = "GO")
               ), 
               column(width = 6, 
                      actionButton(inputId = "back", label = "BACK")
               )
             )
  )
)

Server:

server <- function (session, input, output) {
  disable(id = "back")
  
  observe({
    if (input$go > 0) {
      enable(id = "back")
      disable(id = "go")
    }
  })
  
  observe({
    if (input$back > 0) {
      enable(id = "go")
      disable(id = "back")
    }
  })
}

shinyApp(ui = ui, server = server)

In the MWE, there are only two actionButton, "go" and "back". Initially, the column containing the "back" actionButton should be greyed out. When user click on "go", the column containing "go" should grey out, while the other column become accessible. So far I can only enable and disable actionButton.

Upvotes: 1

Views: 814

Answers (1)

lz100
lz100

Reputation: 7340

library(shiny)
library(shinyjs)

ui <- fluidPage(
    useShinyjs(),
    tags$head(tags$style(
    '
    .grey-out {
        background-color: #eee;
        opacity: 0.2;
    }
    '
    )),
    navbarPage(title = "Grey out",
               tabPanel(title = "test",
                        column(width = 6, id ="left",
                               actionButton(inputId = "go", label = "GO"),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ....")
                        ),
                        column(width = 6, id ="right",
                               actionButton(inputId = "back", label = "BACK"),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ...."),
                               p("some text ....")
                        ),
                        tags$script(
                        '
                        $("#go").click(function(){
                            $("#left").addClass("grey-out");
                            $("#right").removeClass("grey-out");
                        });
                        $("#back").click(function(){
                            $("#right").addClass("grey-out");
                            $("#left").removeClass("grey-out");
                        });
                        '
                        )
               )
    )
)

server <- function (session, input, output) {
    disable(id = "back")
    observe({
        req(input$go)
        enable(id = "right")
        disable(id = "left")
    })

    observe({
        req(input$back)
        enable(id = "left")
        disable(id = "right")
    })
}

shinyApp(ui = ui, server = server)

  1. We give some IDs to the left and right column so later we can easily select them.
  2. I added some p tags to fake some content on the tab.
  3. Add a tags$head(tags$style( tag to add our grey-out class so later we can change the CSS easily. In this class, we change the background color to grey and decrease opacity.
  4. Add some js code from UI so when you click these two buttons, add the grey-out class to change the CSS of the opposite column. I can write the whole thing in js from UI side, no need of shinyjs package, but since you have already used some and I assume you don't have much knowledge of pure js, so I kept your shinyjs code and will not give you too much learning curve.
  5. Instead of disabling the button from the server, we choose the column ID and disable the entire column. So if you select the parent tag, shinyjs will disable all children elements for you.
  6. Also rewrite your observer with more Shiny-ish way.

Upvotes: 2

Related Questions