Last active
October 4, 2018 12:30
-
-
Save zappingseb/40cb90836b870969c72921f5d2745ee8 to your computer and use it in GitHub Desktop.
Example of a difficult custom input shiny application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(shiny) | |
library(glue) | |
library(jsonlite) | |
source("DifficultInput.R") | |
## As this is a GIST, copy the custom_inputs_difficult.js | |
dir.create("www") | |
file.copy("custom_inputs_difficult.js","www/custom_inputs_difficult.js", overwrite = TRUE) | |
ui <- fluidPage( | |
tags$head( | |
tags$link(rel = "stylesheet", type = "text/css", href = "https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.css"), | |
tags$script(src="https://cdnjs.cloudflare.com/ajax/libs/spectrum/1.8.0/spectrum.js"), | |
tags$script(src="custom_inputs_difficult.js") | |
), | |
# Generate a row with a sidebar | |
sidebarLayout( | |
# Define the sidebar with one custom input | |
sidebarPanel( | |
DifficultInput(id="myid") | |
), | |
mainPanel( | |
tableOutput(outputId = "thetext") | |
) | |
) | |
) | |
server <- function(input, output) { | |
# Render the inputs as a table | |
output$thetext <- renderTable(jsonlite::fromJSON(input$myid)) | |
} | |
shinyApp(ui, server) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Difficult Input Binding | |
// | |
// Definition of a Shiny InputBinding extension to | |
// get the values of two color pickers. | |
// | |
// https://github.com/zappingseb/customshinyinput | |
// Author: Sebastian Wolf | |
// License: MIT | |
// ----------------------------------------------------- | |
// Create a shiny input binding | |
// Each custom input needs to be a shiny input binding | |
// that is defined by the JavaScript class "Shiny" and | |
// using the method "InputBinding" | |
// The name can be chosen, here it is "DifficultInputBinding" | |
var DifficultInputBinding = new Shiny.InputBinding(); | |
// Extend the binding with the functions seen here | |
$.extend(DifficultInputBinding, { | |
// The scope defines how the element is described in HTML code | |
// The best way to find the scope | |
find: function(scope) { | |
return $(scope).find(".difficultinput"); | |
}, | |
getValue: function(el) { | |
// create an empty output array | |
var output = [] | |
// go over each input element inside the | |
// defined InputBinding and add the ID | |
// and the value as a dictionary to the output | |
$(el).find(".difficultinputItem").each(function(inputitem){ | |
output.push({ | |
name: $(this).attr("id"), | |
value: $(this).val() | |
}); | |
}); | |
// return the output as JSON | |
return(JSON.stringify(output)) | |
}, | |
setValue: function(el, value) { | |
// todo | |
}, | |
subscribe: function(el, callback) { | |
// the jQuery "change" function allows you | |
// to notice any change to your input elements | |
$(el).on('change.difficultinputItem', function(event) { | |
callback(false); | |
}); | |
// React slower upon key changes inside the elements e.g. | |
// typing in Textarea | |
$(el).on('keyup.difficultinputItem', function(event) { | |
callback(true); | |
}); | |
}, | |
unsubscribe: function(el) { | |
$(el).off('.difficultinput'); | |
}, | |
getRatePolicy: function() { | |
return { | |
// Can be 'debounce' or 'throttle' | |
policy: 'debounce', | |
delay: 500 | |
}; | |
} | |
}); | |
// Registering the shiny input | |
// | |
// The following function call is used to tell shiny that | |
// there now is a new Shiny.InputBinding that it shall | |
// deal with and that it's functionality can be found in | |
// the variable "DifficultInputBinding" | |
Shiny.inputBindings.register(DifficultInputBinding); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' Function to return a DoubleColorPicker input | |
#' @param id (\code{character}) A web element ID, shall not contain dashes or underscores or colon | |
#' @param col_border (\code{character}) A hex code for the border color default value | |
#' @param col_fill (\code{character}) A hex code for the fill color default value | |
#' @return An \code{shiny::div} element with two color pickers | |
#' @author Sebastian Wolf \email{sebastian@@mail-wolf.de} | |
DifficultInput <- function(id="myinput", col_border = "#f00", col_fill="#00f"){ | |
# Return a div element of class "doubleclorpicker" | |
div( | |
id=id, | |
class="difficultinput", | |
## Create a TextArea input | |
HTML(glue( | |
"<textarea id='{id}-input-bigtext' name='{id}-input-bigtext' class='difficultinputItem'>default text</textarea>")), | |
## Create the border Color input | |
tags$label("Border Color"), | |
HTML(glue("<input type='text' id='{id}-input-border' value='{col_border}' class='difficultinputItem'/>")), | |
## Create the FIll color input | |
tags$label("Fill Color"), | |
HTML(glue("<input type='text' id='{id}-input-fill' value='{col_fill}' class='difficultinputItem'/>")), | |
# Include the Javascript code given by the spectrum.js website | |
HTML( | |
glue( | |
"<script> | |
$('#{id}-input-border').spectrum({{ | |
color: '{col_border}', | |
preferredFormat: 'hex3' | |
}}); | |
$('#{id}-input-fill').spectrum({{ | |
color: '{col_fill}', | |
preferredFormat: 'hex3' | |
}}); | |
</script>" | |
) | |
)# HTML | |
)#div | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment