I have a simple Shiny App and I want to prevent the user of the app from saving and exporting data if they enter in too many characters in the "Project Name" column when modifying the rhandsontable. I found a way to make the letters red as a warning that you are entering too many characters, but I am struggling with finding a way of actually preventing the user from saving the data. Here is my attept at doing that and I cannot figure it out. As always any help would be appreciated.
library(shiny)
library(rhandsontable)
library(tibble)
project_data <- tibble(
"Project Name" = c("Project A", "Project B", "Project C"),
"Project Cost" = c(10000, 15000, 20000),
"Project Status" = c("In Progress", "Completed", "In Progress"),
"Project Start Date" = as.Date(c("2023-01-15", "2022-05-10", "2023-03-20"))
)
modified_data <- reactiveVal(project_data)
ui <- fluidPage(
titlePanel("Project Data"),
fluidRow(
column(12,
rHandsontableOutput("table")
)
),
fluidRow(
column(12,
actionButton("saveButton", "Save")
)
)
)
server <- function(input, output, session) {
modified_data <- reactiveVal(project_data)
output$table <- renderRHandsontable({
rhandsontable(modified_data()) %>%
hot_col("Project Name", allowInvalid = FALSE, renderer = "
function(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
if (value.length > 20) {
td.style.color = 'red';
}
}
")
})
observeEvent(input$saveButton, {
invalid_values <- modified_data()$`Project Name`[nchar(modified_data()$`Project Name`) > 20]
if (length(invalid_values) == 0) {
saved_data <- hot_to_r(input$table)
write.csv(saved_data, file = "saved_project_data.csv", row.names = FALSE)
showModal(
modalDialog(
title = "Success",
"Data has been saved to 'saved_project_data.csv'.",
easyClose = TRUE
)
)
} else {
showModal(
modalDialog(
title = "Warning",
"DATA HAS NOT BEEN SAVED",
easyClose = TRUE
)
)
}
})
}
shinyApp(ui, server)
You need a validator
here. Say you want to allow the user to only enter strings of maximum length 10 in the project name
column, then the following would prevent saving a longer character value into a cell and print an error message in case of the user tries to do this.
validator = "
function (value, callback) {
setTimeout(function(){
callback(value.length < 11);
if (value.length > 10) {
alert('more than 10 characters!');
}
}, 1000)
}
"
library(shiny)
library(rhandsontable)
library(tibble)
project_data <- tibble(
"Project Name" = c("Project_A", "Project_B", "Project_C"),
"Allowed" = c("yes", "no", "")
)
modified_data <- reactiveVal(project_data)
ui <- fluidPage(titlePanel("Project Data"),
fluidRow(column(12,
rHandsontableOutput("table"))),
fluidRow(column(12,
actionButton(
"saveButton", "Save"
))))
server <- function(input, output, session) {
modified_data <- reactiveVal(project_data)
output$table <- renderRHandsontable({
rhandsontable(modified_data()) %>%
hot_col(
"Project Name",
allowInvalid = FALSE,
validator = "
function (value, callback) {
setTimeout(function(){
callback(value.length < 11);
if (value.length > 10) {
alert('more than 10 characters!');
}
}, 1000)
}
"
)
})
observeEvent(input$saveButton, {
invalid_values <-
modified_data()$`Project Name`[nchar(modified_data()$`Project Name`) > 20]
if (length(invalid_values) == 0) {
saved_data <- hot_to_r(input$table)
write.csv(saved_data,
file = "saved_project_data.csv",
row.names = FALSE)
showModal(
modalDialog(
title = "Success",
"Data has been saved to 'saved_project_data.csv'.",
easyClose = TRUE
)
)
} else {
showModal(modalDialog(
title = "Warning",
"DATA HAS NOT BEEN SAVED",
easyClose = TRUE
))
}
})
}
shinyApp(ui, server)