Mostafa90
Mostafa90

Reputation: 1706

Use actionButton with updateSelectInput in a shiny app

I Have a shiny app that use UpdateselectInput, I want to add a actionButton because there are some bugs whis the updateselectInput alone. It doesnt seem to work, I want to show the table only if I action the button My app is similar to this one :

library(shiny)
library(dplyr)
library(DT)

ui <- fluidPage(

  titlePanel("Title"),

  sidebarLayout(
    sidebarPanel(width=3,
                 selectInput("filter1", "Filter 1", multiple = TRUE, choices = c("All", LETTERS)),
                 selectInput("filter2", "Filter 2", multiple = TRUE, choices = c("All", as.character(seq.int(1, length(letters), 1)))),
                 selectInput("filter3", "Filter 3", multiple = TRUE, choices = c("All", letters)),
                 actionButton("go_button", "GO !")),

    mainPanel(
      DT::dataTableOutput("tableprint")
    )
  )
)

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

  output$tableprint <- DT::renderDataTable({
    input$go_button
    # Data
    df <- tibble(LETTERS = rep(LETTERS, 2), Numbers = as.character(1:52),
                 letters = paste(LETTERS, Numbers, sep = ""))

    df1 <- df

    if("All" %in% input$filter1){
      df1
    } else if (length(input$filter1)){
      df1 <- df1[which(df1$LETTERS %in% input$filter1),]
    }

    # Update selectInput choices based on the filtered data. Update 'selected' to reflect the user input.
    updateSelectInput(session, "filter1", choices = c("All", df$LETTERS), selected = input$filter1)
    updateSelectInput(session, "filter2", choices = c("All", df1$Numbers), selected = input$filter2)



    if("All" %in% input$filter2){
      df1
    } else if (length(input$filter2)){
      df1 <- df1[which(df1$Numbers %in% input$filter2),]
    }
    updateSelectInput(session, "filter3", choices = c("All", df1$letters), selected = input$filter3)

    if("All" %in% input$filter3){
      df1
    } else if (length(input$filter3)){
      df1 <- df1[which(df1$letters %in% input$filter3),]
    }
    datatable(df1)

  })
}

# Run the application 
shinyApp(ui = ui, server = server)

Thanks for help !

Upvotes: 1

Views: 2230

Answers (1)

krish
krish

Reputation: 1438

Are you looking for something like this?? Only when you click on the Go button, will the table display now. The way the filters work are just the same.

library(shiny)
library(dplyr)
library(DT)

ui <- fluidPage(

  titlePanel("Title"),

  sidebarLayout(
    sidebarPanel(width=3,
                 selectInput("filter1", "Filter 1", multiple = TRUE, choices = c("All", LETTERS)),
                 selectInput("filter2", "Filter 2", multiple = TRUE, choices = c("All", as.character(seq.int(1, length(letters), 1)))),
                 selectInput("filter3", "Filter 3", multiple = TRUE, choices = c("All", letters)),
                 actionButton("go_button", "GO !")),

    mainPanel(
      DT::dataTableOutput("tableprint")
    )
  )
)

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


  goButton <- eventReactive(input$go_button,{
    # Data
    df <- tibble(LETTERS = rep(LETTERS, 2), Numbers = as.character(1:52),
                 letters = paste(LETTERS, Numbers, sep = ""))

    df1 <- df

    if("All" %in% input$filter1){
      df1
    } else if (length(input$filter1)){
      df1 <- df1[which(df1$LETTERS %in% input$filter1),]
    }

    # Update selectInput choices based on the filtered data. Update 'selected' to reflect the user input.
    updateSelectInput(session, "filter1", choices = c("All", df$LETTERS), selected = input$filter1)
    updateSelectInput(session, "filter2", choices = c("All", df1$Numbers), selected = input$filter2)



    if("All" %in% input$filter2){
      df1
    } else if (length(input$filter2)){
      df1 <- df1[which(df1$Numbers %in% input$filter2),]
    }
    updateSelectInput(session, "filter3", choices = c("All", df1$letters), selected = input$filter3)

    if("All" %in% input$filter3){
      df1
    } else if (length(input$filter3)){
      df1 <- df1[which(df1$letters %in% input$filter3),]
    }
    datatable(df1)
  })

  output$tableprint <- DT::renderDataTable({
    goButton()

  })
}

# Run the application 
shinyApp(ui = ui, server = server)

I have moved the filter code to a eventReactive function. So when you click on the button, it will subset your data based on the filters. And the output$tableprint function calls this reactive function, so you will see the table only when you click on the button.

Upvotes: 4

Related Questions