3

I want to do some operations on the server side based on whether the box is collapsed or not. Is it possible to know on the server side if a box in shiny dashboard is collapsed or not?

[EDIT]:

After going through the link provided by warmoverflow and going through the following link I came up with the following code:

ui.R

library(shiny)
library(shinydashboard)
library(shinyjs)


ui <- shinyUI( dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(  

    useShinyjs(),
    extendShinyjs(text = jscode),

    box(id="box1", title = "BOX 1", collapsible = TRUE, collapsed = TRUE ),
    box(id="box2", title = "BOX2",  collapsible = TRUE, collapsed = TRUE),
    # a shiny element to display unformatted text
    verbatimTextOutput("results"),
    verbatimTextOutput("results1"),

    # # javascript code to send data to shiny server
    tags$script("
                document.getElementsByClassName('btn btn-box-tool')[0].onclick = function() {
                var number = document.getElementsByClassName('box-body')[0].style.display;
                Shiny.onInputChange('mydata', number);
                };
                "),

    tags$script("
                document.getElementsByClassName('btn btn-box-tool')[1].onclick = function() {
                var number = document.getElementsByClassName('box-body')[1].style.display;
                Shiny.onInputChange('mydata1', number);
                };
                "),

    actionButton("Collapse", "CollapseAll")

    )


    ))

server.R

library(shiny)
library(shinydashboard)
library(shinyjs)

jscode <- "
shinyjs.collapse = function(boxid) {
$('#' + boxid).closest('.box').find('[data-widget=collapse]').click();
}
"


server <- shinyServer(function(input, output, session) {

  output$results = renderPrint({
    input$mydata
  })

  output$results1 = renderPrint({
    input$mydata1
  })

  observeEvent(input$Collapse,{

    if(input$mydata == "none" || input$mydata == "")
    {
      js$collapse("box1")
    }


    if(input$mydata1 == "none" || input$mydata == "")
    {
      js$collapse("box2")
    }




  })

})

I was wondering if there is a better way to do this. Instead of adding tags$script for each of the box is it possible to make changes to the code such that we can find out all the box that are not collapsed?

Community
  • 1
  • 1
SBista
  • 7,479
  • 1
  • 27
  • 58
  • If there is a Javascript variable that can show the status on the client side, you can use https://ryouready.wordpress.com/2013/11/20/sending-data-from-client-to-server-and-back-using-shiny/ to send the value to server. – Xiongbing Jin Jul 02 '16 at 00:07
  • @warmoverflow I have no knowledge of javascript at all. I tried following the link you mentioned but couldn't figure out how to get an id for the collapsible data-widget. – SBista Jul 06 '16 at 09:32

1 Answers1

0

From your question, I'm not sure if you just want to collapse all expanded boxes or do something else. You can solve the first using a conditional statement in the JS code. Similarly, you can implement a button to expand all boxes using negation (if (!.....)).

library(shiny)
library(shinydashboard)
library(shinyjs)

jscode <- "
shinyjs.collapse = function(boxid) {
if (document.getElementById(boxid).parentElement.className.includes('collapsed-box')) {
$('#' + boxid).closest('.box').find('[data-widget=collapse]').click();
}
}"

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(  
    useShinyjs(),
    extendShinyjs(text = jscode),
    box(id="box1", title = "BOX1", collapsible = TRUE, collapsed = FALSE ),
    box(id="box2", title = "BOX2",  collapsible = TRUE, collapsed = FALSE),
    # a shiny element to display unformatted text
    actionButton("Collapse", "CollapseAll")
  ))

server <- shinyServer(function(input, output, session) {
  observeEvent(input$Collapse,{
    for (i in 1:2) {
      js$collapse(paste0('box',i))
    }
  })
})

shinyApp(ui = ui, server = server)
Tom
  • 532
  • 3
  • 11