I am working on a Shiny app that reads data from a CSV and allows a user to filter the data according to text inputs. The table is editable, however any changes made in browser are not saved.
app.R
library(shiny)
library(shinydashboard)
library(dplyr)
library(readr)
# read CSV into data frame
items <- read_csv("example.csv")
# setup UI - text fields to search CSV
ui <- fluidPage(
img(src="logo.PNG", align='center'),
fluidRow(
column(2,
textInput("id", width="100%", label = "ID"),
),
column(2,
textInput("name", width="100%", label = "Name"),
),
column(2,
textInput("biz", width="100%", label = "Business"),
),
column(2,
textInput("city", width="100%", label = "City"),
),
column(2,
textInput("country", width="100%", label = "Country"),
),
column(12, align="center", style="padding:5px;",
actionButton("go", "Search Results", width="95%", align="center")
),
HTML("<hr width=100%>")
),
mainPanel(
# download button to be rendered in output
column(9,uiOutput("box")),
# table to be rendered in output
DT::dataTableOutput("out")
)
)
# Define server logic required to filter CSV table according to text inputs
server <- function(input, output) {
observeEvent(input$go,{
# filter display table according to text inputs, then sort alphabetically by name
displayTable <- items %>%
filter(grepl(input$id, id, ignore.case = TRUE) | input$id == "") %>%
filter(grepl(input$name, name, ignore.case = TRUE) | input$name == "") %>%
filter(grepl(input$biz, biz, ignore.case = TRUE) | input$biz == "") %>%
filter(grepl(input$city, city, ignore.case = TRUE) | input$city == "") %>%
filter(grepl(input$country, country, ignore.case = TRUE) | input$country == "") %>%
# sort table by name
arrange(tolower(name))
# render the table
output$out <- DT::renderDataTable(DT::datatable(displayTable, editable=TRUE, options = list(searching=TRUE, iDisplayLength = 100, dom = 'Bfrtip')))
# render the download button
output$download <- downloadHandler(
filename = function(){"ItemList.csv"},
content = function(fname){
write.csv(displayTable, fname, row.names=FALSE)
}
)
output[["box"]] <- renderUI(downloadButton('download',"Download table as CSV"))
})
}
# run the application
shinyApp(ui = ui, server = server)
example.csv
id,name,biz,city,country
1,Jack,Finance,Frankfurt,Germany
2,Jane,Insurance,Minneapolis,USA
3,John,Software,San Francisco,USA
I have tried other solutions I have found here that use a reactive table, but they appear to break functionality with the text inputs and filtering. Would there be a simple way to save any changes made in browser back to the CSV that the app uses to generate the table (example.csv)?
The easiest way is to use
server = FALSE
in therenderDT
. If you want to useserver = TRUE
(the default), you have to use a proxy to update the data at each edit.