custom-input-control

Published by onesixx on

https://shiny.rstudio.com/gallery/custom-input-control.html
https://shiny.rstudio.com/articles/building-inputs.html
https://shiny.rstudio.com/articles/js-build-widget.html

custom input example

library(shiny)

chooserInput <- function(inputId, leftLabel, rightLabel, leftChoices, rightChoices, size=5, multiple=F){
\tleftChoices  <- lapply(leftChoices,  tags$option)
\trightChoices <- lapply(rightChoices, tags$option)
\tif (multiple){ multiple <- "multiple" }else{ multiple <- NULL }
\t
\ttagList(
\t\tsingleton(tags$head(
\t\t\ttags$script(src="js/chooser-binding.js"),
\t\t\ttags$style(type="text/css", HTML("
\t\t\t\t.chooser{
\t\t\t\t\tdisplay: flex;
\t\t\t\t\tjustify-content: center;
\t\t\t\t\talign-items: center;
\t\t\t\t}
\t\t\t\t.chooser-container { 
\t\t\t\t\tdisplay: inline-block;
\t\t\t\t\tmargin: 0 6px;
\t\t\t\t}"
\t\t\t))
\t\t)),
\t\tdiv(id=inputId, class="chooser",
\t\t\tdiv(class="chooser-container chooser-left-container",
\t\t\t\t\ttags$select(class="left", size=size, multiple=multiple, leftChoices)),
\t\t\tdiv(class="chooser-container chooser-center-container",
\t\t\t\t\ticon("arrow-circle-o-right", "right-arrow fa-2x"),
\t\t\t\t\ttags$br(),
\t\t\t\t\ticon("arrow-circle-o-left",  "left-arrow fa-2x")\t),
\t\t\tdiv(class="chooser-container chooser-right-container",
\t\t\t\t\ttags$select(class="right", size=size, multiple=multiple, rightChoices))
\t\t)
\t)
}

registerInputHandler("customInput.chooser", function(data, ...){
\tif (is.null(data))
\t\tNULL
\telse
\t\tlist(left=as.character(data$left), right=as.character(data$right))
}, force=T)



ui <- fluidPage(
\tactionButton("btn_loadData", "Load Data"),
\t
\tselectInput("slt_mainData", "Data",\tchoices="Not Loaded!"),
\tuiOutput("chooser"), 
\tverbatimTextOutput("rsltChooser"),
\t
\tactionButton("btn_strData", "Show Data"),
\tverbatimTextOutput("rsltData")
)

server <- function(input, output, session){
\tinit_env1 <- function() {
\t\tenv <- new.env()
\t\treturn(env)
\t}
\tenv1 <- init_env1()

\tobserveEvent(input$btn_loadData, {
\t\tdataList <- data.table(value=1:2, name=c("iris", "USArrests"))
\t\tval        <- as.list(dataList$value)
\t\tnames(val) <- str_c(dataList$value, dataList$name, sep=" : ")
\t\t
\t\tupdateSelectInput(session, "slt_mainData",
\t\t\t\t\t\t\t\t\t\t\tchoices = val,
\t\t\t\t\t\t\t\t\t\t\tselected = 1)
\t})
\t
\trct_select_mainData <- reactive(input$slt_mainData)
\tobserve({
\t\tselect_mainData <- rct_select_mainData()
\t\tif (!is.na(select_mainData) && !select_mainData %in% c("Not Loaded!", "")){
\t\t\tif (is.null(select_mainData)){
\t\t\t\treturn()
\t\t\t}else{
\t\t\t\tswitch(select_mainData,
\t\t\t\t\t"1"={env1$dataset <- iris %>% data.table() },
\t\t\t\t\t"2"={env1$dataset <- USArrests %>% data.table()}
\t\t\t\t)
\t\t\t\tchooseList <- env1$dataset %>% colnames()
\t\t\t\toutput$chooser <- renderUI({
\t\t\t\t\tchooserInput("chooserCol", "Available frobs", "Selected frobs", 
\t\t\t\t\t\t\t\t\t\t\t  chooseList, c(), size=10, multiple=T)
\t\t\t\t})
\t\t\t\toutput$rsltChooser <- renderPrint(
\t\t\t\t\tinput$chooserCol
\t\t\t\t)
\t\t\t}
\t\t}
\t})
\t
\tobserveEvent(input$btn_strData, {
\t\tcol <-  input$chooserCol$right
\t\tif(length(col)>0){
\t\t\toutput$rsltData <- renderPrint(
\t\t\t\tenv1$dataset[ , ..col]
\t\t\t)
\t\t}else{\t
\t\t\treturn()
\t\t}
\t})
}

shinyApp(ui, server)","wrapLines":false,"highlightStart":"85","highlightEnd":"88
(function() {
\tfunction updateChooser(chooser) {
\t\tchooser = $(chooser);
\t\tvar left = chooser.find("select.left");
\t\tvar right = chooser.find("select.right");
\t\tvar leftArrow = chooser.find(".left-arrow");
\t\tvar rightArrow = chooser.find(".right-arrow");
\t\t
\t\tvar canMoveTo = (left.val() || []).length > 0;
\t\tvar canMoveFrom = (right.val() || []).length > 0;
\t\t
\t\tleftArrow.toggleClass("muted", !canMoveFrom);
\t\trightArrow.toggleClass("muted", !canMoveTo);
\t}
\t
\tfunction move(chooser, source, dest) {
\t\tchooser = $(chooser);
\t\tvar selected = chooser.find(source).children("option:selected");
\t\tdest = chooser.find(dest);
\t\tdest.children("option:selected").each(function(i, e) {e.selected = false;});
\t\tdest.append(selected);
\t\tupdateChooser(chooser);
\t\tchooser.trigger("change");
\t}
\t
\t$(document).on("change", ".chooser select", function() {
\t\tupdateChooser($(this).parents(".chooser"));
\t});
\t
\t$(document).on("click", ".chooser .right-arrow", function() {
\t\tmove($(this).parents(".chooser"), ".left", ".right");
\t});
\t
\t$(document).on("click", ".chooser .left-arrow", function() {
\t\tmove($(this).parents(".chooser"), ".right", ".left");
\t});
\t
\t$(document).on("dblclick", ".chooser select.left", function() {
\t\tmove($(this).parents(".chooser"), ".left", ".right");
\t});
\t
\t$(document).on("dblclick", ".chooser select.right", function() {
\t\tmove($(this).parents(".chooser"), ".right", ".left");
\t});
\t
\tvar binding = new Shiny.InputBinding();
\t
\tbinding.find = function(scope) {
\t\treturn $(scope).find(".chooser");
\t};
\t
\tbinding.initialize = function(el) {
\t\tupdateChooser(el);
\t};
\t
\tbinding.getValue = function(el) {
\t\treturn {
\t\t\tleft:  $.makeArray($(el).find("select.left option").map(function(i, e) { return e.value; })),
\t\t\tright: $.makeArray($(el).find("select.right option").map(function(i, e){ return e.value; }))
\t\t};
\t};
\t
\tbinding.setValue = function(el, value) {
\t\t// TODO: implement
\t};
\t
\tbinding.subscribe = function(el, callback) {
\t\t$(el).on("change.chooserBinding", function(e) {
\t\t\tcallback();
\t\t});
\t};
\t
\tbinding.unsubscribe = function(el) {
\t\t$(el).off(".chooserBinding");
\t};
\t
\tbinding.getType = function() {
\t\treturn "customInput.chooser";
\t};
\t
\tShiny.inputBindings.register(binding, "customInput.chooser");
\t
})();
Categories: R-Shiny

onesixx

Blog Owner

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x