I use the sweetalertR package to create a confirmation message in the UI (reason for using this package: it looks very nice and the message is highly customizable).
However, I need to implement some code in the server function so that the file is only saved to disk if the confirmation message has been approved. Currently it saves the file already on clicking the save button.
Problem: the sweetalert function seems to have no inputID argument!
library(shiny) #1.5.0
library(shinydashboard) #0.7.1
library(rhandsontable) #0.3.7
# remotes::install_github("timelyportfolio/sweetalertR")
library(sweetalertR) #0.2.0
library("xlsx") #0.6.5
shinyApp(
ui = fluidPage(
box(width = 12,
# Save button
actionButton(inputId = "saveBtn", "Save"),
br(),
# Editable table
rHandsontableOutput("submit_data_edit_table"),
# Confirmation button, see: http://www.buildingwidgets.com/blog/2015/6/29/week-25-sweetalertr
sweetalert(selector = "#saveBtn", text = 'Changes will be saved in a new excel file',
title = 'Confirm changes',
type = "warning",
allowOutsideClick = TRUE,
showCancelButton = TRUE,
cancelButtonText = 'Cancel',
confirmButtonText = 'Confirm',
confirmButtonColor = "darkred",
closeOnConfirm = FALSE,
evalFunction = 'function(){swal("Saved", "Restart the application", "success")}'
)
)
),
server = function(input, output, session) {
# Create a table that can be modified
output$submit_data_edit_table = renderRHandsontable({
if (!is.null(input$submit_data_edit_table)) {
DF = hot_to_r(input$submit_data_edit_table)
} else {
DF = iris
}
rhandsontable(DF,
height = 750
) %>%
hot_table(highlightCol = TRUE, highlightRow = TRUE)
})
# Save file based on button press
observe({
# Save button
input$saveBtn
submit_data_edit_table = isolate(input$submit_data_edit_table)
if (!is.null(submit_data_edit_table)) {
# Save table as Excel file
write.xlsx(hot_to_r(input$submit_data_edit_table), file = "newData.xlsx",
sheetName = "Tot",
col.names = TRUE, row.names = FALSE,
append = FALSE)
}
})
}
)
I found a solution: using shinyalert instead. It offers the same functionality and design but is better documented.
I included the following code in the server function:
# Create global variable for confirmation message response
global <- reactiveValues(response = FALSE)
# Update file after table change
observeEvent(input$saveBtn, {
# Trigger confirmation dialog
shinyalert(title = "Confirm changes",
text = "Changes will be saved in a new excel file",
type = "warning",
closeOnClickOutside = TRUE,
showCancelButton = TRUE,
cancelButtonText = 'Cancel',
showConfirmButton = TRUE,
confirmButtonText = 'Confirm',
confirmButtonCol = "darkred",
timer = 15000, # 15 seconds
callbackR = function(x) {
global$response <- x
shinyalert(title = "Saved",
text = "Restart the application",
type = "success")
}
)
print(global$response)
observe({
req(input$shinyalert)
if (!global$response == "FALSE") {
submit_data_edit_table = isolate(input$submit_data_edit_table)
if (!is.null(submit_data_edit_table)) {
# Save as Excel file
write.xlsx(hot_to_r(input$submit_data_edit_table), file = "newData.xlsx",
sheetName = "Tot",
col.names = TRUE, row.names = FALSE,
append = FALSE)
}
# Reset value
global$response <- "FALSE"
} # End of confirmation button if
}) # End of observe
}) # End of observeEvent
And in the UI you simply need to set up shinyalert:
# Set up shinyalert to create confirmation messages
useShinyalert(),
Don't forget to load the package first!
library(shinyalert)
Related
I am trying to place a button inside the datatable where if the user wants to reset the sorted column they can hit the button and table gets reset or changed to it's original order. At the moment, when I press the button, it is not triggering any event on click. The event should replace the data in the server part.
I am currently following these posts:
shiny DT datatable - reset filters
https://github.com/rstudio/DT/issues/76
Reset a DT table to the original sort order
However, in the last two posts above, even though they get the job done, the button is not part of the datatable.
Here is my reprex:
library(DT)
library(shiny)
library(shinyjs)
# function placed in the global.R
clearSorting <- function(proxy) {
shinyjs::runjs(paste0("$('#' + document.getElementById('", proxy$id,"').getElementsByTagName('table')[0].id).dataTable().fnSort([]);"))
}
# ui.R
ui <- fluidPage(
DT::DTOutput(outputId = "table"),
shinyjs::useShinyjs()
)
# servcer.R
server <- function(input, output) {
output$table <- renderDT({
DT::datatable(data = iris,
filter = 'top',
extensions = c('Buttons'),
options = list(scrollY = 600,
scrollX = TRUE,
autoWidth = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
buttons = list(
list(
extend = '',
text = 'Reset Table',
action = JS("function() {document.getElementById('reset_sort').click();}")
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE))
})
observeEvent(input$reset_sort, {
data <- iris
clearSorting(proxy = DT::dataTableProxy(outputId = "table"))
DT::replaceData(proxy = DT::dataTableProxy(outputId = "table"),
data = data,
rownames = FALSE)
})
}
shinyApp(ui = ui, server = server)
Here is a way:
library(DT)
js <- c(
"function(e, dt, node, config){",
" dt.iterator('table', function(s){",
" s.aaSorting.length = 0;",
" s.aiDisplay.sort(function(a,b){",
" return a-b;",
" });",
" s.aiDisplayMaster.sort(function(a,b){",
" return a-b;",
" });",
" }).draw();",
"}"
)
datatable(
iris,
extensions = "Buttons",
options = list(
dom = "Bfrtip",
buttons = list(
list(
extend = "collection",
text = "Reset columns order",
action = JS(js)
)
)
)
)
To use it in Shiny, you may need to set server = FALSE in renderDT:
output$table <- renderDT({
......
}, server = FALSE)
I am creating an app where the users can download the plot displayed. I want the user to be able to click download and ShinyAlert will pop up to ask for filename as the input.
So far the file gets downloaded if I press on save. However, when the CancelButton is clicked, shiny tries to download the page's HTML, with a "Failed - Server problem".
I placed an if function inside downloadHandler so that when input$shinyalert != FALSE the downloadHandler will execute the code, but I couldn't find the fault in my code. Any help will be appreciated, thanks.
Here is the code:
UI:
ui <- fluidPage(
useShinyalert(),
plotOutput("vmgraph"),
actionButton("downloadPlot", "Download Plot")
useShinyjs(),
## hide the downloadButton and only display actionButton
conditionalPanel(
"false",
downloadButton("downloadData")
)
)
Server:
observeEvent(input$downloadPlot, {
shinyalert("Save as:",
type = "input",
size = "m",
closeOnEsc = TRUE,
closeOnClickOutside = TRUE,
showConfirmButton = TRUE,
showCancelButton = TRUE,
confirmButtonText = "Save",
confirmButtonCol = "#0075B8",
animation = TRUE)
})
output$downloadData <- downloadHandler(
filename = function() {
if (input$shinyalert != FALSE) {
paste(input$shinyalert, ".png", sep = "")}},
content = function(file) {
if (input$shinyalert != FALSE) {
ggsave(file, plot = vmgraph(), width = 12, height = 7.7)
}})
observeEvent(input$shinyalert, {
## Click on the downloadButton when input$shinyalert is updated
shinyjs::runjs("$('#downloadData')[0].click();")
})
Perform your check for the cancel button before you get into the downloadHandler:
library(shiny)
library(shinyjs)
library(shinyalert)
library(ggplot2)
gg <- ggplot(mtcars, aes(mpg)) +
geom_boxplot()
ui <- fluidPage(
useShinyalert(),
plotOutput("vmgraph"),
actionButton("downloadPlot", "Download Plot"),
useShinyjs(),
## hide the downloadButton and only display actionButton
conditionalPanel(
"false",
downloadButton("downloadData")
)
)
server <- function(input, output) {
observeEvent(input$downloadPlot, {
shinyalert("Save as:",
type = "input",
size = "m",
closeOnEsc = TRUE,
closeOnClickOutside = TRUE,
showConfirmButton = TRUE,
showCancelButton = TRUE,
confirmButtonText = "Save",
confirmButtonCol = "#0075B8",
animation = TRUE
)
})
output$downloadData <- downloadHandler(
# do not perform check here
filename = function() {
paste(input$shinyalert, ".png", sep = "")
},
content = function(file) {
ggsave(file, plot = gg, width = 12, height = 7.7)
}
)
observeEvent(input$shinyalert, {
## Click on the downloadButton when input$shinyalert is updated
# perform the check here
if (input$shinyalert != FALSE) {
shinyjs::runjs("$('#downloadData')[0].click();")
}
})
}
shinyApp(ui = ui, server = server)
Problem: I have the following app. Essentially, I want to press the button to load the data. After the first time I load the data via button press I want to get ask if I want to save my changes. If yes, confirmation that changes were successfully saved, else show some other data (other data not included).
Approach I tried to solve it with observeEvent expressions which are triggered via reactiveValues. However, as you will observe when running the script below, this does not work out as expected.
Question: Any idea on what is wrong?
library(shiny)
library(shinyWidgets)
library(rhandsontable)
shinyApp(
ui = fluidPage(
actionButton("show", "Show data", width = "100%"),
rHandsontableOutput("data_table")
),
server = function(input, output) {
rv <- reactiveValues(
# Triggers
pressed_first_time = 0,
confirm_module = TRUE,
save_module = TRUE,
table_change = TRUE
)
observeEvent(input$show, ignoreInit = TRUE, {
if (rv$pressed_first_time == 0){
rv$pressed_first_time <- isolate(rv$pressed_first_time + 1)
rv$table_change <- isolate(!rv$table_change)
cat("pressed_first time")
} else {
rv$pressed_first_time <- isolate(rv$pressed_first_time + 1)
rv$confirm_module <- isolate(!rv$confirm_module)
}
})
observeEvent(rv$confirm_module, ignoreInit = TRUE,{
confirmSweetAlert(
session = session,
inputId = session$ns("show_confirmation"),
title = "Be careful, your changes might be lost",
text = "Do you want to save your changes?",
type = "question",
btn_labels = c("Cancel", "Save"),
btn_colors = NULL,
closeOnClickOutside = FALSE,
showCloseButton = FALSE,
html = FALSE
)
cat("confirmation module")
rv$save_module <- isolate(!rv$save_module)
})
observeEvent(rv$save_module, ignoreInit = TRUE, {
if (isTRUE(input$show_confirmation)) {
sendSweetAlert(
session = session,
title = "Saved",
text = "Updated data has been successfully saved",
type = "success"
)
rv$table_change <- isolate(!rv$table_change)
cat("saving module")
} else {
return()
}
})
data_to_modify <- eventReactive(rv$table_change, ignoreInit = TRUE, {
mtcars
})
handson_df <- eventReactive(rv$table_change, ignoreInit = TRUE, {
cat("create handsons")
req(data_to_modify())
rhandsontable(data_to_modify())
})
output$data_table <- renderRHandsontable({
cat("plot module")
req(handson_df())
htmlwidgets::onRender(handson_df(),change_hook)
})
}
)
I think its just that you need session inside the server, as in:
server = function(input, output, session) {...
Actually, I found out the problem. The link from data_to_modify to handson_df was missing. In the below solution I put them together but in principle adding another reactiveValue triggering handson_df from data_to_modify will also work
library(shiny)
library(rhandsontable)
shinyApp(
ui = fluidPage(
actionButton("show", "Show data", width = "100%"),
rHandsontableOutput("data_table")
),
server = function(input, output) {
rv <- reactiveValues(
# Triggers
pressed_first_time = 0,
confirm_module = TRUE,
save_module = TRUE,
table_change = TRUE
)
observeEvent(input$show, ignoreInit = TRUE, {
if (rv$pressed_first_time == 0){
rv$pressed_first_time <- 1
rv$table_change <- isolate(!rv$table_change)
cat("pressed_first time")
} else {
rv$pressed_first_time <- 1
rv$confirm_module <- isolate(!rv$confirm_module)
}
})
observeEvent(rv$confirm_module, ignoreInit = TRUE,{
confirmSweetAlert(
session = session,
inputId = session$ns("show_confirmation"),
title = "Be careful, your changes might be lost",
text = "Do you want to save your changes?",
type = "question",
btn_labels = c("Cancel", "Save"),
btn_colors = NULL,
closeOnClickOutside = FALSE,
showCloseButton = FALSE,
html = FALSE
)
})
observeEvent(input$show_confirmation, ignoreInit = TRUE, {
if (isTRUE(input$show_confirmation)) {
sendSweetAlert(
session = session,
title = "Saved",
text = "Updated data has been successfully saved",
type = "success"
)
rv$table_change <- isolate(!rv$table_change)
cat("saving module")
} else {
return()
}
})
data_to_modify <- eventReactive(rv$table_change, ignoreInit = TRUE, {
rhandsontable(mtcars)
})
# handson_df <- eventReactive(rv$table_change, ignoreInit = TRUE, {
# cat("create handsons")
# req(data_to_modify())
# rhandsontable(data_to_modify())
# })
output$data_table <- renderRHandsontable({
cat("plot module")
req(data_to_modify())
data_to_modify()
# htmlwidgets::onRender(handson_df(),change_hook)
})
}
)
My aim is to refresh .Rdata objects when the user confirms a dataset reloading through a shinyalert pop up. A small example below. Before loading the app I've created and saved 2 objects (DatasetNumber1 and DatasetNumber2) containing a label and data to be displayed.
When the app is launched I load by default DatasetNumber1 objects thanks to the global.R file. So now test and data objects from DatasetNumber1 are accessible through server.R AND ui.R, which I need to (not in this example, but in my full app).
I want the user to be able to select the other dataset via the dropdown to refresh the global R objects and in the end the plotting.
The print statement in the server.R, after I've selected the other dataset in the dropdown, clicked on the Load button and validate through the shinyalert, confirms that the dropdown input changed but the load statement does not refresh R objects.
I've tried to make the loading reactive straight in the global.R script but I ended with the same result. Maybe the rendering is faster than the loading and so does not take the updated data in account to render...
In any case I do not want to reload neither the app nor the session.
Thanks !
#inputCreation.R
test <- "IamDatasetNumber1"
data <- c(1, 3, 6, 4, 9)
save(test, data, file = "./Test/DatasetNumber1.Rdata")
test <- "IamDatasetNumber2"
data <- c(2, 7, 9, 12, 13)
save(test, data, file = "./Test/DatasetNumber2.Rdata")
#global.R
library(shiny)
library(shinyjs)
library(shinyalert)
load("DatasetNumber1.Rdata")
#ui.R
shinyUI(
fluidPage(
useShinyjs(),
div(
id = "main_page",
fluidRow( # -------------------------------------------------------
column(
2, offset=0,
selectInput("dropdown_dataset", "Dataset :", choices=c("DatasetNumber1", "DatasetNumber2"), selected="DatasetNumber1")
),
column(
1, offset=0,
useShinyalert(),
actionButton("button_dataset", "Load"),
)
),
fluidRow( # -------------------------------------------------------
uiOutput("test_text")
),
fluidRow( # -------------------------------------------------------
plotOutput("test_plot")
)
)
)
)
#server.R
shinyServer(
function(input, output, session) {
observeEvent(input$button_dataset, {
shinyalert(title = "Are you sure?",
text = "This action can take a while",
type = "warning",
closeOnEsc = TRUE,
closeOnClickOutside = TRUE,
showCancelButton = TRUE,
showConfirmButton = TRUE,
confirmButtonText = "OK",
confirmButtonCol = "#AEDEF4",
cancelButtonText = "Cancel",
inputId = "shinyalert",
callbackR = function(x){
if(x){
showModal(modalDialog("Loading...", footer=NULL))
print(paste(input[["dropdown_dataset"]],sep=""))
load(paste(input[["dropdown_dataset"]],".Rdata",sep=""))
removeModal()
}
}
)
})
output$test_text <- renderText(test)
output$test_plot <- renderPlot(plot(data))
}
)
I changed the initialization of react_data. You should get rid of the load from your global file. This way the dataset can be garbage collected when you switch. Otherwise, it will exist in .GlobalEnv forever.
Try this server:
shinyServer(
function(input, output, session) {
react_data <- reactiveVal()
react_data(local({load("DatasetNumber1.Rdata"); data}))
observeEvent(
input$shinyalert,
{
req(input$shinyalert)
load(paste(input$dropdown_dataset,".Rdata",sep=""))
react_data(data)
})
observeEvent(input$button_dataset, {
shinyalert(title = "Are you sure?",
text = "This action can take a while",
type = "warning",
closeOnEsc = TRUE,
closeOnClickOutside = TRUE,
showCancelButton = TRUE,
showConfirmButton = TRUE,
confirmButtonText = "OK",
confirmButtonCol = "#AEDEF4",
cancelButtonText = "Cancel",
inputId = "shinyalert",
callbackR = function(x){
if(x){
showModal(modalDialog("Loading...", footer=NULL))
print(paste(input[["dropdown_dataset"]],sep=""))
removeModal()
}
}
)
})
output$test_text <- renderText(test)
output$test_plot <- renderPlot(plot(react_data()))
}
)
With #Tyler's help !
#server.R
shinyServer(
function(input, output, session) {
react <- reactiveVal()
react(local({load("DatasetNumber1.Rdata"); list(test=test,data=data)}))
observeEvent(
input$shinyalert,
{
req(input$shinyalert)
load(paste(input$dropdown_dataset,".Rdata",sep=""))
react(list(test=test,data=data))
})
observeEvent(input$button_dataset, {
shinyalert(title = "Are you sure?",
text = "This action can take a while",
type = "warning",
closeOnEsc = TRUE,
closeOnClickOutside = TRUE,
showCancelButton = TRUE,
showConfirmButton = TRUE,
confirmButtonText = "OK",
confirmButtonCol = "#AEDEF4",
cancelButtonText = "Cancel",
inputId = "shinyalert",
callbackR = function(x){
if(x){
showModal(modalDialog("Loading...", footer=NULL))
print(paste(input[["dropdown_dataset"]],sep=""))
removeModal()
}
}
)
})
output$test_text <- renderText(react()$test)
output$test_plot <- renderPlot(plot(react()$data))
}
)
Goal: I would like for the user to upload their own data frame, specify the columns in their data frame that provide "Name", "Longitude", and "Latitude" data, then create a table using DataTable (DT package).
Issue: The data frame appears on the render table after the user makes the selections, but when they attempt to sort each column or interact with the data, or even change a selection for "Name", "Longitude", or "Latitude", the following error message appears on the console:
ERROR: [on_request_read] parse error
Here's my code for the ui and server pages I have (note: I am using dashboardPage for layout):
Reproducible Example
ui <- dashboardPage(
dashboardHeader(title = "Test") ,
dashboardSidebar(
sidebarMenu(
menuItem("Selections", tabName = "selections"),
menuItem("Data Table", tabName = "dataTable")
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "selections",
selectInput("mapChoice",
label = "Choose a map:",
choices = c("",
"New Map from Data Table"),
selected = ""),
conditionalPanel("input.mapChoice == 'New Map from Data Table'",
fileInput("userData",
label = "Choose CSV File",
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
uiOutput("newMapUI")
),
###############################################
# Bookmark widget
shinyURL.ui(width = "400px")
###############################################
),
tabItem(
tabName = "dataTable",
DT::dataTableOutput("table")
)
)
)
)
server <- function(input, output, session) {
############################################################
# Add in function for saving and recording urls as bookmarks
shinyURL.server(session)
############################################################
userData <- reactive({
path <- input$userData
if (is.null(path))
return (NULL)
results <- read.csv(file = path$datapath,
header = TRUE,
stringsAsFactors = FALSE)
results
})
output$newMapUI <- renderUI({
list(
# Specify the column for labeling
if (!is.null(userData())) {
selectizeInput("nameCol",
label = "Choose the column to be used for
point labels: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Name',
maxItems = 1))
},
# Specify longitude column
if (!is.null(userData())) {
selectizeInput("lonCol",
label = "Choose the column containing longitude
values: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Longitude',
maxItems = 1))
},
# Specify latitude column
if (!is.null(userData())) {
selectizeInput("latCol",
label = "Choose the column conatining latitude
values: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Latitude',
maxItems = 1))
}
)
})
nameCol <- reactive({
as.character(input$nameCol)
})
lonCol <- reactive({
as.character(input$lonCol)
})
latCol <- reactive({
as.character(input$latCol)
})
newUserData <- reactive({
if (is.null(userData()))
return (NULL)
# Create the new data frame:
if (length(nameCol()) != 0 &&
length(lonCol()) != 0 &&
length(latCol()) != 0) {
userData <- userData()
name <- nameCol()
lonCol <- lonCol()
latCol <- latCol()
results <- data.frame(Name = userData[, name],
Longitude = userData[, lonCol],
Latitude = userData[, latCol])
results$Name <- as.character(results$Name)
results$Longitude <- as.numeric(results$Longitude)
results$Latitude <- as.numeric(results$Latitude)
}
results
})
mapData <- reactive({
data <- data.frame()
if (input$mapChoice == "New Map from Data Table") {
if (length(nameCol()) != 0 &&
length(lonCol()) != 0 &&
length(latCol() != 0)) {
data <- newUserData()
}
}
data
})
output$table <- DT::renderDataTable({
datatable(mapData(),
extensions = c('Buttons', 'FixedHeader', 'Scroller'),
options = list(dom = 'Bfrtip',
buttons = list('copy', 'print',
list(extend = 'csv',
filename = 'map data',
text = 'Download')
),
scrollX = TRUE,
pageLength = nrow(mapData()),
fixedHeader = TRUE,
deferRender = FALSE,
scrollY = 400,
scroller = FALSE,
autowidth = TRUE
)
)
}
) # End of table render
}
shinyApp(ui = ui, server = server)
Note: If I attempted to use this data for a plot, that will also not work. (Plotting the points on a map is my end goal).
Update1: For some dumb reason, this snippet app runs perfectly fine as expected, yet these lines of code are directly from my application. I will continue to update as more things occur.
Update2: After heavy searching and debugging, I finally caught the source of the error message via help of the js provided by the browser while running the app. The error is trying to use shinyURL in combination with DT and fileInput. My guess is that shinyURL is attempting to save a url, which is entirely too long for the browser, and which provides info that the user gave. In other words, it might be trying to save the fileInput data with the url info..? I'm adding the shinyURL function to the example above, so that it will provide the exact same error message I was stuck on. I don't need a solution immediately, but I am curious about what's really happening. (Lines that produce error are highlighted with ### above and below.
Solution
The issue was expected in my latest update, the combination of the user uploaded file and the interaction of the data frame in DT caused the URL generate by shinyURL to be entirely too long.
To find a work around that allows shinyURL to still be in the application, I did some investigating and discovered that DT output creates its own input objects such as input$tableId_rows_current, which tried to save all of the indices of the table every time the user interacted with. So, as soon as the data frame was too large, any interaction with it would pass a url query error, which showed up on the console in R Studio as ERROR [on_request_read] parse error.
Luckily, shinyURL also has an inherent way of ignoring user selected inputs. How? Just simply place a "." at the beginning of the input ID when creating new widgets. Or, in the case of DT table output, place a period at the beginning of your data table output ID, so that all of the inherent DT inputs are ignored.
Code Solution:
ui <- dashboardPage(
dashboardHeader(title = "Test") ,
dashboardSidebar(
sidebarMenu(
menuItem("Selections", tabName = "selections"),
menuItem("Data Table", tabName = "dataTable")
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "selections",
selectInput("mapChoice",
label = "Choose a map:",
choices = c("",
"New Map from Data Table"),
selected = ""),
conditionalPanel("input.mapChoice == 'New Map from Data Table'",
#########################################################
# Add in a period before file input ID
#########################################################
fileInput(".userData",
label = "Choose CSV File",
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
uiOutput("newMapUI")
),
# # Bookmark widget
shinyURL.ui(width = "400px")
),
tabItem(
tabName = "dataTable",
########################################################
# Add in a period before data table output ID
########################################################
DT::dataTableOutput(".table")
)
)
)
)
server <- function(input, output, session) {
# # Add in function for saving and recording urls as bookmarks
shinyURL.server(session)
userData <- reactive({
path <- input$.userData
if (is.null(path))
return (NULL)
results <- read.csv(file = path$datapath,
header = TRUE,
stringsAsFactors = FALSE)
results
})
output$newMapUI <- renderUI({
list(
# Specify the column for labeling
if (!is.null(userData())) {
selectizeInput("nameCol",
label = "Choose the column to be used for
point labels: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Name',
maxItems = 1))
},
# Specify longitude column
if (!is.null(userData())) {
selectizeInput("lonCol",
label = "Choose the column containing longitude
values: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Longitude',
maxItems = 1))
},
# Specify latitude column
if (!is.null(userData())) {
selectizeInput("latCol",
label = "Choose the column conatining latitude
values: ",
choices = c(names(userData())),
multiple = TRUE,
options = list(placeholder = 'Latitude',
maxItems = 1))
}
)
})
nameCol <- reactive({
as.character(input$nameCol)
})
lonCol <- reactive({
as.character(input$lonCol)
})
latCol <- reactive({
as.character(input$latCol)
})
newUserData <- reactive({
if (is.null(userData()))
return (NULL)
# Create the new data frame:
if (length(nameCol()) != 0 &&
length(lonCol()) != 0 &&
length(latCol()) != 0) {
userData <- userData()
name <- nameCol()
lonCol <- lonCol()
latCol <- latCol()
results <- data.frame(Name = userData[, name],
Longitude = userData[, lonCol],
Latitude = userData[, latCol])
results$Name <- as.character(results$Name)
results$Longitude <- as.numeric(results$Longitude)
results$Latitude <- as.numeric(results$Latitude)
}
results
})
mapData <- reactive({
data <- data.frame()
if (input$mapChoice == "New Map from Data Table") {
if (length(nameCol()) != 0 &&
length(lonCol()) != 0 &&
length(latCol() != 0)) {
data <- newUserData()
}
}
data
})
output$.table <- DT::renderDataTable({
datatable(mapData(),
extensions = c('Buttons', 'FixedHeader', 'Scroller'),
options = list(dom = 'Bfrtip',
buttons = list('copy', 'print',
list(extend = 'csv',
filename = 'map data',
text = 'Download')
),
scrollX = TRUE,
pageLength = nrow(mapData()),
fixedHeader = TRUE,
deferRender = FALSE,
scrollY = 400,
scroller = FALSE,
autowidth = TRUE
)
)
}
) # End of table render
}
shinyApp(ui = ui, server = server)