Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions R/shinymarkdown.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@
#' Create an instance of a Markdown editor for text that may require formatting.
#'
#' @param inputId The \code{input} prefix used to access the value.
#' @param min_height The editor's miniminum height value (pixels). Default = '300px'. Overwritten by the height parameter.
#' @param height The editor's height value, applied as a border-box. Example values include "300px", "100%", and "auto". Defaults to "500px".
#' @param preview_style The Markdown editor's preview style. Either "tab" or "vertical". Default is "tab".
#' @param preview_highlight Should the Markdown Editor's HTML preview have a highlighted element corresponding to the cursor position in the Markdown editor. Default is FALSE.
#' @param initial_edit_type Initial editor type: "markdown" or "wysiwyg". Default is "markdown".
#' @param hide_mode_switch Should the user be able to switch the editor mode from "wysiwyg" to "markdown" or vice versa? Default is TRUE.
#' @param refresh_rate The rate (ms) to send the editor's contents to Shiny.
#' Default is 1000ms. If \code{refresh = "manual"}, the editor will have a
#' button to manually send the editor's contents to Shiny.
#' @param min_height The editor's miniminum height value (pixels). Default =
#' '300px'. Overwritten by the height parameter.
#' @param height The editor's height value, applied as a border-box. Example
#' values include "300px", "100%", and "auto". Defaults to "500px".
#' @param preview_style The Markdown editor's preview style. Either "tab" or
#' "vertical". Default is "tab".
#' @param preview_highlight Should the Markdown Editor's HTML preview have a
#' highlighted element corresponding to the cursor position in the Markdown
#' editor. Default is FALSE.
#' @param initial_edit_type Initial editor type: "markdown" or "wysiwyg".
#' Default is "markdown".
#' @param hide_mode_switch Should the user be able to switch the editor mode
#' from "wysiwyg" to "markdown" or vice versa? Default is TRUE.
#' @param language Editor language ISO code. Defaults to "en-us".
#' @param initial_value Should the editor have text already present? If so, supply a character string. Default is NULL.
#' @param initial_value Should the editor have text already present? If so,
#' supply a character string. Default is NULL.
#'
#' @return An instance of the markdown editor for use within a Shiny App.
#'
Expand Down Expand Up @@ -48,7 +59,12 @@
#'
#' }
#'
mdInput <- function(inputId, min_height = "300px", height = "500px", preview_style = "tab", preview_highlight = FALSE, initial_edit_type = "markdown", hide_mode_switch = TRUE, language = "en-us", initial_value = NULL) {
mdInput <- function(inputId, refresh_rate = 1000, min_height = "300px", height = "500px", preview_style = "tab", preview_highlight = FALSE, initial_edit_type = "markdown", hide_mode_switch = TRUE, language = "en-us", initial_value = NULL) {

# Ensure correct spelling of manual if refresh_rate is non-numeric
if (!is.numeric(refresh_rate) && !grepl("\\bmanual\\b", refresh_rate)) {
stop("`refresh_rate` is not recognized. Please check your spelling and try again.")
}

data <- list(inputId = inputId,
min_height = min_height,
Expand All @@ -59,7 +75,10 @@ mdInput <- function(inputId, min_height = "300px", height = "500px", preview_sty
hide_mode_switch = base::tolower(hide_mode_switch),
language = language,
initial_value_lgl = ifelse(is.null(initial_value), FALSE, TRUE),
initial_value = initial_value
initial_value = initial_value,
manual_lgl = ifelse(refresh_rate == "manual", TRUE, FALSE),
auto_lgl = ifelse(refresh_rate != "manual", TRUE, FALSE),
refresh_rate = refresh_rate
)

template <- readLines(system.file("assets/js/init-template.js", package = "shinymarkdown"))
Expand Down
58 changes: 54 additions & 4 deletions inst/assets/js/init-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,61 @@ const {{inputId}}_editor = new Editor({
{{ /initial_value_lgl }}
});

/* When someone types in the editor, make the markdown and HTML available
as the Shiny/R inputs "shinymd_markdown" and "shinymd_html", respectively. */
$('#' + '{{inputId}}' + '_editor').on('keyup', function() {
{{#auto_lgl}}

// define debounce function
const debounce = function(func, delay) {
let timeout;

return function executed(...args) {
const later = function() {
clearTimeout(timeout);
func(...args);
};

clearTimeout(timeout);
timeout = setTimeout(later, delay);

};

};

// define getEditorContents as a debounced function that sets the Shiny input values appropriately
var getEditorContents = debounce(function() {
Shiny.setInputValue("{{inputId}}" + "_markdown", {{inputId}}_editor.getMarkdown());
Shiny.setInputValue("{{inputId}}" + "_html", {{inputId}}_editor.getHtml());
})
}, {{refresh_rate}});

/* When someone types in the editor, make the markdown and HTML available
as the Shiny/R inputs "shinymd_markdown" and "shinymd_html", respectively.
This occurs after the debounce time to improve performance of Shiny apps.*/
$('#' + '{{inputId}}' + '_editor').on('keyup', getEditorContents);

});

{{ /auto_lgl }}

{{#manual_lgl}}

// create var switchSection which isolates the specific editor's footer button div
switchSection = $('#' + '{{inputId}}' + '_editor .te-mode-switch-section')[0];

// add a new button with sendShiny as its id
$(switchSection).append('<button id = "sendShiny"> Send to Shiny </button>');

// Add the button class and change some CSS defaults
$("#sendShiny").addClass("te-switch-button").css({"height": "19px", "width": "120px"});

// when the button is pressed add the active class and send the Shiny input values
$("#sendShiny").on("mousedown", function() {
$(this).addClass("active");
Shiny.setInputValue("{{inputId}}" + "_markdown", {{inputId}}_editor.getMarkdown());
Shiny.setInputValue("{{inputId}}" + "_html", {{inputId}}_editor.getHtml());
});

// when the button is done being pressed remove the active class
$("#sendShiny").on("mouseup", function() {$(this).removeClass("active");});

});

{{ /manual_lgl }}
27 changes: 20 additions & 7 deletions man/mdInput.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.