firmo23
firmo23

Reputation: 8404

Actionbutton stops display of datatable when file is uploaded for first time

I have the shiny app below in which the user uploads a csv. Then the pickerInput gets the unique values of the first column of that csv and uses them to subset the dataframe and display it in a table. The issue is that I want to use an actionButton in order to apply changes but when the csv is uploaded for first time it should be displayed full and not displayed empty because the actionButton is not triggered yet. For the purpose of the example I have used iris dataset instead of a csv.

# app.R ##
library(shiny)
library(DT)
library(shinyWidgets)
ui <- pageWithSidebar(
  headerPanel('Iris k-means clustering'),
  sidebarPanel(
    fileInput("file1", "Choose CSV File",
              accept = c(
                "text/csv",
                "text/comma-separated-values,text/plain",
                ".csv")
    ),
    uiOutput("id"),

    actionButton("go","Go")
  ),
  mainPanel(
    uiOutput('contents')
  )
)

server <- function(input, output, session) {
  output$id<-renderUI({
    #inFile <- input$file1
    #df2<-data.frame(read.csv(inFile$datapath, header = TRUE))
    pickerInput("select", "Select ID", 
                choices = as.character(unique(iris$Species)), 
                multiple = T,options = list(`actions-box` = TRUE),
                selected = as.character(unique(iris$Species)))
  })
  output$contents <- renderUI({
    input$goButton
    #inFile <- input$file1
    #df<-data.frame(read.csv(inFile$datapath, header = TRUE))
    df<-data.frame(iris)
    df<-subset(iris,Species %in% isolate(input$select))

      renderDataTable({
        datatable(
          df,
          options = list(scrollX = TRUE,pageLength=5)
        )
        })

  })
}

shinyApp(ui = ui, server = server)

Upvotes: 0

Views: 33

Answers (2)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

library(shiny)
library(DT)
library(shinyWidgets)

ui <- pageWithSidebar(
  headerPanel('Iris k-means clustering'),
  sidebarPanel(
    fileInput("file1", "Choose CSV File",
              accept = c(
                "text/csv",
                "text/comma-separated-values,text/plain",
                ".csv")
    ),
    uiOutput("picker"),
    actionButton("go","Go")
  ),
  mainPanel(
    DTOutput("dtable")
  )
)

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

  filteredCSV <- reactiveVal(NULL)

  CSV <- eventReactive(input[["file1"]], {
    dat <- read.csv(input[["file1"]]$datapath, header = TRUE)
    filteredCSV(dat)
    dat
  })


  output[["picker"]] <- renderUI({
    req(CSV())
    choices <- unique(as.character(CSV()[,1]))
    pickerInput("select", "Select ID", 
                choices = choices, 
                multiple = TRUE, options = list(`actions-box` = TRUE),
                selected = choices)
  })

  observeEvent(input[["go"]], {
    req(CSV())
    filteredCSV(CSV()[CSV()[,1] %in% input[["select"]],])
  })

  output[["dtable"]] <- renderDT({
    req(filteredCSV())
    datatable(
      filteredCSV(), 
      options = list(scrollX = TRUE, pageLength = 5)      
    )
  })

}

shinyApp(ui = ui, server = server)

Upvotes: 1

user12728748
user12728748

Reputation: 8506

This is in reply to the previous version of your post, but should solve the main problem - this is how I would go about it, using reactive expressions (and data.table, but you might just as well not use it):

library(shiny)
library(shinyWidgets)
library(DT)
library(data.table)

ui <- pageWithSidebar(
    headerPanel('Iris k-means clustering'),
    sidebarPanel(
        fileInput("file1", "Choose CSV File",
                  accept = c(
                      "text/csv",
                      "text/comma-separated-values,text/plain",
                      ".csv")
        ),
        uiOutput("id"),
        #actionButton("go","Go")
    ),
    mainPanel(
        DT::dataTableOutput('contents')
    )
)

server <- function(input, output, session) {
    getFile <- reactive({
        req(input$file1)
        fread(input$file1$datapath, header = TRUE)
    })

    output$contents <- DT::renderDataTable({
        DT::datatable(getFile()[get(colnames(getFile())[1]) %in% input$select])
    })

    output$id <- renderUI({
        req(getFile())
        df <- getFile()
        pickerInput("select", "Select ID", 
                    choices = unique(df[[1]]), 
                    multiple = TRUE, options = list(`actions-box` = TRUE),
                    selected = unique(df[[1]]))
    })
}

shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions