I am trying to build a shiny app to retrieve data from an Oracle table based on user specified ID. I want to create one file with data for each ID and download it to the default downloads folder. I would also like to zip the files and provide the user with that one file. Also, the app is just to download the data and I really don't want a main Panel hence the width of the mainPanel is zero. If that's not the way to do it, please let me know.The app is going to reside on a server and hence the need for a download Handler. Below is my code. Any help is greatly appreciated.
library(shiny)
library(ROracle)
library(shinyjs)
library(shinyalert)
library(shinyWidgets)
ui <- fluidPage(
useShinyjs(),
useShinyalert(),
# Application title
titlePanel(fluidRow(
column(10, "RAINFALL AND ET DATA RETRIEVAL",align="center"),
column(2, offset = 0,img(height =90,width=250,src="logo.png",align="left"))
)),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(width = 12,
helpText("Please enter IDs separated by commas. You can enter up to 25 IDs."),
textInput("PixelID", "Pixel ID(s)", value = ""),
helpText("OR"),
fileInput('datafile','Choose csv file to upload Pixel IDs.The csv file should have Pixel IDs in the first column WITHOUT ANY HEADER.',accept = c('csv','comma-separated-values','.csv')),
helpText("Please select a parameter you would like to retrieve."),
radioButtons("ParameterType", "Parameters",
choices = c("Rainfall Estimates","Evapotranspiration Estimates"),
selected = "None"),
dateInput("startdate","Data From", format = "yyyy-mm-dd",max = Sys.Date()),
dateInput("enddate","Data To", format = "yyyy-mm-dd",max = Sys.Date()),
br(), br(),
actionBttn("goButton","Go!",color = "default",style = "fill",size = "lg"),
br(),br(),
uiOutput("download"),
mainPanel(width=0)
)
)
server <- function(input, output, session) {
data<-eventReactive(input$goButton,{
if(is.null(input$PixelID) || input$PixelID == ""){
req(input$datafile)
infile<-input$datafile
PixelList<-read.table(infile$datapath, header = FALSE, sep = ",", stringsAsFactors = FALSE)
colnames(PixelList)<-"PixelNum"
PixelList_comma<-paste(PixelList$PixelNum, collapse = ",")} else{
if(input$PixelID != ""){
PixelList<-data.frame(strsplit(input$PixelID,","))
colnames(PixelList)<-"PixelNum"
PixelList_comma<-input$PixelID
}}
drv <- dbDriver("Oracle")
connection <- dbConnect(drv, username = "xxxx", password = "xxxxx", dbname = "xxxx")
if(input$ParameterType=="Rainfall Estimates"){
for(i in 1:nrow(PixelList)){
raindata<-dbGetQuery(connection, paste("select PIXEL, TO_CHAR(tsdatetime_dt, 'MM/DD/YYYY HH24:MI') as DATE_TIME, tsvalue_ms as RAINFALL from xxxx
where feature_id =",PixelList[i,1]," order by tsdatetime_dt", sep=""))
}
dbDisconnect(conn = connection)
}
return(raindata)
})
output$download <- renderUI({
downloadButton("downloadData", "Download")
})
output$downloadData <- downloadHandler(
filename = function() {
paste("testnexrad",".zip",sep = "")
},
content = function(file) {
for(i in 1:nrow(PixelList)){
#No idea what to do here
}
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Related
Unable to publish the shiny app properly and append data in sql table?
Can some one help resolve this..I want to create a form that takes input from the user and when click on submit it uploads that data to sql table. below is the code
require(shiny)
require(jpeg)
require(tm)
require(magick)
require(pdftools)
require(magrittr)
library(pdfsearch)
require(readxl)
require(shinythemes)
require(tesseract)
require(tidyverse)
require(foreach)
library(data.table)
library(DT)
library(uuid)
library(shinyjs)
library(dplyr)
library(odbc)
require(DBI)
library(RSQLite)
require(stringr)
df<-data.frame(ID=character(),file=character(),c=character(),d=integer(),e=integer(),date=as.character(),
stringsAsFactors = FALSE)
dbWriteTable(con,"contracting_assistant",df,overwrite=FALSE,append=TRUE)
##Ui
`
library(shiny)
library(DT)
#library(shinyjs)
#source("/Users/SSACHD12/Desktop/Project/display_code.R")
source("/Users/SSACHD12/Desktop/Project/delete_display_file.R")
#files[grepl("_comp",files)==FALSE]
#files[grep("_comp",files)]
#jscode <- "shinyjs.refresh = function() { history.go(0); }"
ui <- pageWithSidebar(
headerPanel("Contracting Assistant"),
sidebarPanel(
#useShinyjs(),
#extendShinyjs(text = jscode),
shinyjs::useShinyjs(),
#shinyjs::inlineCSS(appCSS),
fluidRow(
column(width = 8, offset = 1 , div(style = "height:10px"),
position=c("left"),fluid=TRUE,
selectInput("file_name", "File to Select:",choices=list.files("www/",pattern = "pdf$"))
)
),
fluidRow(actionButton("add_button","Add",icon("plus")),
actionButton("edit_button","Edit",icon("edit")))
#actionButton("refresh", "Refresh app")
),
mainPanel(
# Use imageOutput to place the image on the page
splitLayout(
dataTableOutput('Main_table'))
)
)
`
##Server
shinyServer(function(input, output) {
con <- dbConnect(RSQLite::SQLite(),Driver = "SQL Server",
Server = "XXXXXx",
Database = "XXXXXX",
Port = 1433)
df<-reactive({
input$submit
input$submit_edit
dbReadTable(con,"contracting_assistant")
})
#EntryForm
entry_form<-function(button_id){
showModal(
modalDialog(
div(id="entry_form"),
tags$head(tags$style(".model-dialog{width:400px}")),
tags$head(tags$style(HTML(".shiny-split-layout>div{overflow:visible}"))),
fluidPage(
fluidRow(
splitLayout(
cellWidths = c("250px","250px"),
cellArgs = list(style = "vertical-align:top"),
textInput("c",label="C",placeholder = ""),
textInput("d",label="D",placeholder = ""),
textInput("e",label="E",placeholder = ""),
actionButton(button_id,"Submit")
),
easyClose=TRUE
)
)
)
)
}
# #Add Data
formData<-reactive({
formData <- data.frame(ID=UUIDgenerate(),
file=str_replace(input$file_name,".pdf",""),
c=input$c,
d=input$d,
e=input$e,
date=as.character(format(Sys.time(),format="%Y-%m-%d %H:%M:%S")),
stringsAsFactors = FALSE)
return(formData)
})
#Append data to SQL
appendData <- function(data){
query<-sqlAppendTable(con,"contracting_assistant",data,row.names = FALSE)
dbExecute(con,query)
}
observeEvent(input$add_button,priority = 20,{
entry_form("submit")
})
observeEvent(input$submit,priority = 20,{
appendData(formData())
shinyjs::reset("entry_form")
removeModal()
})
output$Main_table<-DT::renderDataTable({
table<-df() %>% select(-ID)
names(table)<-c("file","c","d","e","date")
table<-datatable(table,rownames = FALSE,
options=list(searching =FALSE, lengthChange=FALSE)
)
})
}
)
Can some one help resolve this..I want to create a form that takes input from the user and when click on submit it uploads that data to sql table.
I have a set of scripts which are run from below, with aspects of the final output influenced by lines 2-4
setwd()
inputyear = ""
inputmonth = ""
dataType = ""
source("1.R")
source("2.R")
source("3.R")
source("4.R")
source("5.R")
#input required file name
saveWorkbook(wb, "Workbook.xlsx", overwrite = TRUE)
I'd like to be able to change the input year, input month, dataType and the name of the workbook produced by the source() 1-5, from a shiny app, and then run the respective files and generate the excel file.
So far I have the following code, which does not produce any errors, but does not function as desired.
I have only included the 'server' section of the code to save space, and this is the part I need help with if possible;
ui<-shinyUI(fluidPage(theme = shinytheme("flatly"),
tags$head(
tags$style(HTML(
".shiny-output-error-validation {
color; green;
}
"))
),
basicPage(
headerPanel("Workbook"),
sidebarPanel(
selectInput("inputmonth","Select Publication Month",c("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC")),
selectInput("inputyear","Select Year",c("2018/19","2019/20","2020/21")),
selectInput("dataType","Select Version",c("provisional","final"))),
textInput("WorkBookName","Enter File Name (include .xlsx)"),
actionButton("Generate", "Generate Workbook"))
))
server <- function(input, output, session){
observeEvent(input$Generate, {
validate(need(input$WorkBookName != "", "Please enter file name"))
req(input$inputmonth, input$inputyear, input$dataType, input$WorkBookName)
inputyear = input$inputmonth
inputmonth = input$inputyear
dataType = input$dataType
source("1.R",local = TRUE)
source("2.R", local = TRUE)
source("3.R", local = TRUE)
source("4.R", local = TRUE)
source("5.R", local = TRUE)
saveWorkbook(wb, paste0(input$WorkBookName, ".xlsx"), overwrite = TRUE)
})
}
shinyApp(ui, server)
How can I alter the server script to get the desired functionality?
edit: Full script added, sourced names removed
You'll somehow need to trigger the execution of your reactive code. Reactive code only is executed if it was invalidated. Please see this for further information.
In the following app the code will be executed once the Save Workbook button is clicked.
I don't know your UI and sourced R-scripts, so you might want to replace here accordingly:
library(shiny)
library(openxlsx)
library(shinythemes)
ui <- shinyUI(fluidPage(
theme = shinytheme("flatly"),
tags$head(tags$style(
HTML(".shiny-output-error-validation {
color; green;
}
")
)),
basicPage(
headerPanel("Workbook"),
sidebarPanel(
selectInput(
"inputmonth",
"Select Publication Month",
toupper(month.abb)
),
selectInput("inputyear", "Select Year", c("2018/19", "2019/20", "2020/21")),
selectInput("dataType", "Select Version", c("provisional", "final"))
),
textInput("WorkBookName", "Enter File Name (include .xlsx)"),
actionButton("Generate", "Generate Workbook"),
uiOutput("test")
)
))
server <- function(input, output, session) {
observeEvent(input$Generate, {
req(input$inputmonth,
input$inputyear,
input$dataType,
input$WorkBookName)
inputyear = input$inputmonth
inputmonth = input$inputyear
dataType = input$dataType
# source("1.R", local = TRUE)
# source("2.R", local = TRUE)
# source("3.R", local = TRUE)
# source("4.R", local = TRUE)
# source("5.R", local = TRUE)
#
# saveWorkbook(wb, paste0(input$WorkBookName, ".xlsx"), overwrite = TRUE)
output$test <- renderUI("Everything fine...")
})
}
shinyApp(ui, server)
I'm relatively new to using R and shiny. Currently, I'm getting the Error: Conflict (HTTP 409) when trying to access an html file from dropbox and this is fine, I know the reason. What I do have a problem with is trying to find a way to change Error code message.
I've tried a couple forms of validation and try-catches.
library(shiny)
library(rdrop2)
library(httr)
ui <- # Define UI for dataset viewer application
shinyUI(pageWithSidebar(
headerPanel("Test DropBox html Docs to Shiny"),
sidebarPanel(
selectInput("Cat", "Choose a Category:",
choices = c("A", "B", "C")),
selectInput("Year", "Choose a Year:",
choices = c("2012", "2011")),
downloadButton("downFile", "Download File"),
width = 2),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Html Pages", htmlOutput("viewReport"))),
width = 10)
)
)
#IMPORTANT: The two lines below needs to be run just one time unless the token is deleted
# Create Token
token <- drop_auth()
# Save token
saveRDS(token, "droptoken.rds")
token <- readRDS("droptoken.rds")
server <- shinyServer(function(input, output) {
# ---------------------------------------------------
filePutReport <- reactive(
paste(input$Cat, "_", input$Year, "_Doc.html", sep = "")
)
filePutReport2 <- reactive({
# Search if the file exists in DropBox
drop_download(path = paste("shiny_docs/shinydbtest/", filePutReport(), sep = ""),
overwrite = TRUE, local_path = "./www",
dtoken = token)
filePutReport()
})
# Show Html Pages
output$viewReport <- renderUI({
tags$iframe(seamless = "seamless", width = "1400", height = "1000",
src = filePutReport2()
)
})
###
output$downFile <- downloadHandler(
# generate bins based on input$bins from ui.R
filename = function() {
paste0(filePutReport() )
},
content = function(file){
file.copy(from = paste0("./www/", filePutReport2() ), to = file, overwrite = TRUE)
}
)
})
shinyApp(ui = ui, server = server)
Instead of simply "Error: Conflict (HTTP 409)", I would a message a client might be able to understand. Any and all suggestions are welcome. Thank you in advance for your help.
In my current environment I cannot establish a connection to dropbox, but please try the approach below. I first deleted the last line refering to filePutReport() in your filePutReport2() reactive, since they are the same and you want your call to drop_download to produce either a value (TRUE) or an invisible object of class "try-error". Therefore, you need to further wrap your call to drop_download in a try statement. This way filePutReport2() either contains the value TRUE or an invisible object of class "try-error". Then you should be able to use a need/validate function in your renderUI statement including a custom error message. I hope it's working, since I can't test it.
library(shiny)
library(rdrop2)
library(httr)
ui <- # Define UI for dataset viewer application
shinyUI(pageWithSidebar(
headerPanel("Test DropBox html Docs to Shiny"),
sidebarPanel(
selectInput("Cat", "Choose a Category:",
choices = c("A", "B", "C")),
selectInput("Year", "Choose a Year:",
choices = c("2012", "2011")),
downloadButton("downFile", "Download File"),
width = 2),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Html Pages", htmlOutput("viewReport"))),
width = 10)
)
)
#IMPORTANT: The two lines below needs to be run just one time unless the token is deleted
# Create Token
token <- drop_auth()
# Save token
saveRDS(token, "droptoken.rds")
token <- readRDS("droptoken.rds")
server <- shinyServer(function(input, output) {
# ---------------------------------------------------
filePutReport <- reactive(
paste(input$Cat, "_", input$Year, "_Doc.html", sep = "")
)
filePutReport2 <- reactive({
# Search if the file exists in DropBox
try({
drop_download(path = paste("shiny_docs/shinydbtest/", filePutReport(), sep = ""),
overwrite = TRUE, local_path = "./www",
dtoken = token)
}, silent = TRUE)
})
# Show Html Pages
output$viewReport <- renderUI({
validate(
need(filePutReport2(), 'Custom error message!'))
tags$iframe(seamless = "seamless", width = "1400", height = "1000",
src = filePutReport()
)
})
###
output$downFile <- downloadHandler(
# generate bins based on input$bins from ui.R
filename = function() {
paste0(filePutReport() )
},
content = function(file){
file.copy(from = paste0("./www/", filePutReport2() ), to = file, overwrite = TRUE)
}
)
})
shinyApp(ui = ui, server = server)
I am new to R and i am using shiny package to build a shiny app that can take different type of queries and those queries takes dynamic user id provided by users on ui level and also i want to show the demo of result of query on ui.
So, my problem is that i am not able to store the query results into an data frame also on clicking on Download button csv is not storing in my system. my code is below. thanks.
###server
library(shiny)
library(RMySQL)
shinyServer(function(input, output) {
datasetInput <- reactive({
switch(input$queryset,
"CDR" = cdr,
"ASSET" = ast,
"USAGE" = usg)
})
output$tbl <- renderTable({
conn <- dbConnect(drv = RMySQL::MySQL(),dbname = "xxxx",
host = "xxxxxx",
username = "xxxxx",
password = "xxxxx"),
q<-dbSendQuery(conn,paste0("select * from table where user_id='",input$user_id,"' and start_time >= '2016-07-16' and start_time < '2016-07-28' order by start_time limit 10 ;",sep = ""
))
dat<- dbFetch(q,n=-1)
on.exit(dbDisconnect(conn), add = TRUE)
})
output$view <- renderTable({
head({dat}, n = input$nrows)
})
output$downloadData <- downloadHandler(
filename = function() { paste(input$user_id, '.csv', sep='') },
content = function(file) {
write.csv({dat}, file)
})
}
)
###ui
library(shiny)
shinyUI(fluidPage(
titlePanel("My App"),
sidebarLayout(
sidebarPanel(
selectInput("queryset", "Choose the type of query:",
choices = c("CDR", "ASSET", "USAGE")),
numericInput("nrows", "Enter the no. of observations:", 10),
numericInput("user_id", "Enter user_id:", 0),
downloadButton('downloadData', 'Download',class = NULL)
),
mainPanel(
tableOutput("view")
)
)
))
I'm building a simple shiny app which will take inputs from the user and fetch data from a table in the DB and take the number of records to be downloaded as an input and provide a download file option.
Everything below works just fine. My only concern is the textInput bar( variable : uiOutput("text") in the ui and output$text in the server) appears only after the datatableOutput is displayed. I do not understand why this happens.
Ideally, I want the textInput bar ('uiOutput("text")') object to be displayed once the leaf(i.e. input$leaf1 is not null) is selected and then I want the datatableOutput to be displayed and then the Download Button should come up.
Is there a way I can achieve this? Thanks
library(shiny)
library(shinydashboard)
#library(stringr)
library(DT)
#library(shinyBS)
ui <- dashboardPage(
dashboardHeader(title = strong("DASHBOARD"),titleWidth = 240),
dashboardSidebar(
sidebarMenu(
selectizeInput("x", "Choose a number:", choices = sort(unique(lftable$x)), multiple = TRUE),
uiOutput("leaf_categ")
)
),
dashboardBody(
fluidRow(
uiOutput("text"),
dataTableOutput("lm_df"),
downloadButton('downloadData', 'Download')
)))
server <- function(input, output){
output$leaf_categ <- renderUI(
selectizeInput("leaf1", "Choose leaf categories:",
choices = reactive(unique(lftable[lftable$num %in% input$x, c("X_NAME")]))(),
multiple = TRUE)
)
#### creates a text input box
#### number of records to be downloaded is provided as input
output$text <- renderUI({
if(is.null(reactive(input$leaf1)())){
return()
}else{
textInput("var1", label = "Enter the number of records to be downloaded", value = "")
}
})
#### fetches data from DB
lm <- reactive({
if(is.null(input$leaf1)){
return()
}else{
leaf_id <- unique(lftable[lftable$X_NAME %in% input$leaf1, c("leaf_id")])
query_str <- paste('select * from table1 where current_date between start_dt and end_dt and score_num >= 0.1 and x in (' , input$x, ')', ' and X_ID in (', leaf_id, ')', ';', sep = "")
}
lm_data <- getDataFrmDW(query_str)
})
###creates a download tab
output$downloadData <- downloadHandler(
filename = function() { paste("lm_user_data", '.csv', sep='') },
content = function(file) {
lm_df <- lm()
lm_df <- lm_df[1:(as.integer(input$text)),]
print(dim(lm_df))
write.csv(lm_df, file, row.names = F)
})
output$lm_df <- DT::renderDataTable(lm())
}
shinyApp(ui, server)