Search code examples
rshinylabelreactiveshinybs

change label of shiny button and counting clicks


I was trying to switch the label of a show/hide columns button, and also keep the track of the number of times it is clicked in order to alter the number of columns showed of a table. I made it, but I couldn't use a direct even/odd differentiation of the value of the counter. Instead I had to use this: (vars$counter+1)/2) %% 2 == 0) to make it work, because each click changes the counter 2 times. I would like to request an easier procedure, maybe there is a shinyBS for that?

## app.R ##
library(shiny)
library(shinydashboard)
library(DT)

body<-dashboardBody(
  textOutput("count"),
  uiOutput('showallcolumnsbutton'),
  DT::dataTableOutput('table2')
)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  body
)

server <- function(input, output) {
  table<-data.frame(replicate(10,sample(0:1,1000,rep=TRUE)))
  vars<-reactiveValues()
  vars = reactiveValues(counter = 0)
  observe({
    if(!is.null(input$showallcolumns)){
      input$showallcolumns
      isolate({
        vars$counter <- vars$counter + 1
      })
    }
  })
  label <- reactive({
    if(!is.null(input$showallcolumns)){
      if( ( (vars$counter+1)/2) %% 2 == 0) label <- "Hide"
      else label <- "Show"
    }
  })
  output$showallcolumnsbutton <- renderUI({
    actionButton("showallcolumns", label = label(),
                 icon("hand-pointer-o"),
                 style="color: #000; background-color: #0099ff; border-color: #2e6da4" 
    )
  })
  output$count<-renderText({paste("counter value:",vars$counter)})
  columnstoshow = reactive ({
    x=  ((vars$counter+1)/2) # %% 2 == 0)
    if (!is.null (x))
    {
      if (x %% 2 == 0) {
        c=c(1:10)
      }
      else {
        c=c(1:5)
      }
    } #end 1st if
    else {
      c=c(1:10)
    }
  })
  output$table2 = DT::renderDataTable({
    DT::datatable(table[, columnstoshow()])
  })

} # end server

shinyApp(ui, server)

Solution

  • Since Im not 100% what you want, is this it? Note that I used other library such as shinyBS

    rm(list = ls())
    library(shiny)
    library(shinydashboard)
    library(DT)
    library(shinyBS)
    
    body <- dashboardBody(bsButton("showallcolumns", label = "Hide", block = F, style="danger",icon=icon("hand-pointer-o")),br(),DT::dataTableOutput('table2'))
    ui <- dashboardPage(dashboardHeader(),dashboardSidebar(),body)
    
    server <- function(input, output,session) {
    
      table <- data.frame(replicate(10,sample(0:1,1000,rep=TRUE)))
      vars <- reactiveValues(counter = 1:10)
    
      observeEvent(input$showallcolumns,{
        if(input$showallcolumns %% 2){
          updateButton(session, "showallcolumns",label = "Show", block = F, style = "success",icon=icon("hand-pointer-o")) 
          vars$counter <- 1:5
        }
        else{
          updateButton(session, "showallcolumns",label = "Hide", block = F, style = "danger",icon=icon("hand-pointer-o"))    
          vars$counter <- 1:10
        }                                                                                                                        
      })  
    
      output$table2 = DT::renderDataTable({
        DT::datatable(table[, vars$counter])
      })
    
    } # end server
    
    shinyApp(ui, server)