From b3a9c797ed34bab54f261b473a8598f8511558e7 Mon Sep 17 00:00:00 2001 From: Pingfan Hu Date: Thu, 3 Oct 2024 23:03:31 -0400 Subject: [PATCH] sweetalert --- NAMESPACE | 1 + NEWS.md | 1 + R/server.R | 66 ++++++++++++++++++++++++----------------- inst/css/surveydown.css | 5 ++++ man/sd_server.Rd | 9 ++++++ 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index ff24c8e8..9138c8ce 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,6 +29,7 @@ export(sd_update) export(sd_version) import(rstudioapi) import(shiny) +import(shinyWidgets) importFrom(digest,digest) importFrom(rsconnect,deployApp) importFrom(shiny,HTML) diff --git a/NEWS.md b/NEWS.md index c0d978a5..90c62193 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ - `sd_server()` now has a new parameter called `auto_scroll`. It's default to `TRUE`, which enables auto scrolling that tracks the user's input, can be turned off by changing to `FALSE`. Thanks to the contribution from [Zain Hoda](https://github.com/zainhoda1). - `sd_question()` now has the `"matrix"` type. The [documentation page](https://surveydown.org/question-types#matrix) is updated. - Asterisk, as an indication of required questions, is now moved to the top right corner of question containers. +- Replaced the default shiny alert with `sweetalert`. # surveydown 0.3.2 diff --git a/R/server.R b/R/server.R index 0615c123..c23b0c83 100644 --- a/R/server.R +++ b/R/server.R @@ -18,6 +18,7 @@ #' @param auto_scroll Logical. Whether to enable auto-scrolling to the next question after answering. Defaults to TRUE. #' #' @import shiny +#' @import shinyWidgets #' @importFrom stats setNames #' @importFrom shiny reactiveValuesToList observeEvent renderText #' @@ -33,6 +34,7 @@ #' \item Performs database operations or saves to a local CSV file in preview mode. #' \item Sets up admin functionality if enabled in the configuration. #' \item Controls auto-scrolling behavior based on the `auto_scroll` parameter. +#' \item Uses sweetalert for warning messages when required questions are not answered. #' } #' #' @section Progress Bar: @@ -50,12 +52,18 @@ #' after the current question is answered. This behavior can be disabled by setting #' `auto_scroll` to FALSE. #' +#' @section Warning Messages: +#' The function uses sweetalert to display warning messages when users attempt to proceed +#' without answering all required questions. This provides a more user-friendly experience +#' compared to standard Shiny notifications. +#' #' @return #' This function does not return a value; it sets up the server-side logic for the Shiny application. #' #' @examples #' \dontrun{ #' library(surveydown) +#' library(shinyWidgets) #' db <- sd_database() #' #' shinyApp( @@ -308,10 +316,10 @@ sd_server <- function( # Page navigation ---- check_required <- function(page) { - all(vapply(page$required_questions, function(q) { - is_visible <- is_question_visible(q) - !is_visible || check_answer(q, input) - }, logical(1))) + all(vapply(page$required_questions, function(q) { + is_visible <- is_question_visible(q) + !is_visible || check_answer(q, input) + }, logical(1))) } is_question_visible <- function(q) { @@ -321,31 +329,33 @@ sd_server <- function( # Determine which page is next, then update current_page_id() to it observe({ - lapply(pages, function(page) { - observeEvent(input[[page$next_button_id]], { - shiny::isolate({ - current_page_id <- page$id - next_page_id <- get_default_next_page(page, page_ids, page_id_to_index) - next_page_id <- handle_skip_logic(input, skip_if, current_page_id, next_page_id) - if (!is.null(next_page_id) && check_required(page)) { - # Set the current page as the next page - current_page_id(next_page_id) - - # Update the page time stamp - next_ts_id <- page_ts_ids[which(page_ids == next_page_id)] - all_data[[next_ts_id]] <- get_utc_timestamp() - - # Update tracker of which fields changed - changed_fields(c(changed_fields(), next_ts_id)) - } else if (!is.null(next_page_id)) { - shiny::showNotification( - "Please answer all required questions before proceeding.", - type = "error" - ) - } - }) - }) + lapply(pages, function(page) { + observeEvent(input[[page$next_button_id]], { + shiny::isolate({ + current_page_id <- page$id + next_page_id <- get_default_next_page(page, page_ids, page_id_to_index) + next_page_id <- handle_skip_logic(input, skip_if, current_page_id, next_page_id) + if (!is.null(next_page_id) && check_required(page)) { + # Set the current page as the next page + current_page_id(next_page_id) + + # Update the page time stamp + next_ts_id <- page_ts_ids[which(page_ids == next_page_id)] + all_data[[next_ts_id]] <- get_utc_timestamp() + + # Update tracker of which fields changed + changed_fields(c(changed_fields(), next_ts_id)) + } else if (!is.null(next_page_id)) { + shinyWidgets::sendSweetAlert( + session = session, + title = "Warning", + text = "Please answer all required questions before proceeding.", + type = "warning" + ) + } + }) }) + }) }) # Observer to max out the progress bar when we reach the last page diff --git a/inst/css/surveydown.css b/inst/css/surveydown.css index 38937213..ef5fcd22 100644 --- a/inst/css/surveydown.css +++ b/inst/css/surveydown.css @@ -282,3 +282,8 @@ p:last-child, font-weight: normal; padding-left: 15px; /* Add some left padding */ } + +/* SweetAlert custom styling */ +.swal2-popup { + font-size: 1rem !important; +} diff --git a/man/sd_server.Rd b/man/sd_server.Rd index bcfd1793..455cba7c 100644 --- a/man/sd_server.Rd +++ b/man/sd_server.Rd @@ -52,6 +52,7 @@ The function performs the following tasks: \item Performs database operations or saves to a local CSV file in preview mode. \item Sets up admin functionality if enabled in the configuration. \item Controls auto-scrolling behavior based on the \code{auto_scroll} parameter. +\item Uses sweetalert for warning messages when required questions are not answered. } } \section{Progress Bar}{ @@ -75,9 +76,17 @@ after the current question is answered. This behavior can be disabled by setting \code{auto_scroll} to FALSE. } +\section{Warning Messages}{ + +The function uses sweetalert to display warning messages when users attempt to proceed +without answering all required questions. This provides a more user-friendly experience +compared to standard Shiny notifications. +} + \examples{ \dontrun{ library(surveydown) + library(shinyWidgets) db <- sd_database() shinyApp(