2016-04-27 5 views
1

Ich versuche, ein benutzerdefiniertes Eingabe-Widget für Shiny (folgende: http://shiny.rstudio.com/articles/building-inputs.html), die jQuery UI Limitslider() Wrapping - im Grunde möchte ich einen Schieberegler mit 3 Knoten paraMaterize a Dreiecksverteilung. Ich bemühe mich, Shiny dazu zu bringen, die Veränderungsereignisse zu "sehen".Shiny Custom Input Binding für LimitSlider

Hier sind meine app.R Skript:

library(shiny) 

limitSlider <- function(id, label, a, b, c, min = a, max = b) { 
    div(class = 'form-group shiny-input-container', 
     tags$label(label), 
     div(class = "ui-limitslider", 
      id = id, 
      `data-a` = a, 
      `data-b` = b, 
      `data-c` = c, 
      `data-min` = min, 
      `data-max` = max) 
    ) 
} 

ui <- shinyUI(fluidPage(

    tags$head(
    tags$link(rel = "stylesheet", type = "text/css", 
       href = "jquery-ui.css") 
), 

    tags$head(
    tags$link(rel = "stylesheet", type = "text/css", 
       href = "limitslider.css") 
), 

    tags$head(
    tags$script(src = "jquery-ui.js") 
), 

    tags$head(
    tags$script(src = "limitslider.js") 
), 

    tags$head(
    tags$script(src = "limitslidershiny.js") 
), 

    tags$head(
    tags$script(src = "limitsliderinputbinding.js") 
), 

    titlePanel("Test Limit Slider"), 

    sidebarLayout(
    sidebarPanel(
     limitSlider("test1", "Test 1:", a = 25, b = 110, c = 80, 
        min = 0, max = 200), 
    ), 
    mainPanel(
     tableOutput("values") 
    ) 
) 
)) 


server <- shinyServer(function(input, output) { 

    sliderValues <- reactive({ 

    data.frame(
     Name = c("test1"), 
     Value = c(as.character(c(paste(input$test1, collapse = ' ')))) 
    ) 

    }) 

    output$values <- renderTable({ 
    sliderValues() 
    }) 

}) 

# Run the application 
shinyApp(ui = ui, server = server) 

Wie Sie lade ich eine Folge von CSS und JS-Dateien an der Spitze sehen können, um die Sache Arbeit zu machen - sie leben in einem „www“ Verzeichnis. Hier ist meine limitslidershiny.js Datei - und ich glaube nicht, das Problem hier ist:

$(function() { 

    $('.ui-limitslider').each(function(){ 

    // a,b,c correspond to the rtriangle function signature 
    var a = $(this).data('a'); 
    var c = $(this).data('c'); 
    var b = $(this).data('b'); 

    // the rest of these correspond to the limitslider API 
    var min = $(this).data('min'); 
    var max = $(this).data('max'); 

    $(this).limitslider({ 
     values: [a, c, b], 
     gap: 0, 
     label: true, 
     min: min, 
     max: max 
    }); 
    }); 
}); 

Hier ist mein limitsliderinputbinding.js Skript:

var limitSliderInputBinding = new Shiny.InputBinding(); 

$.extend(limitSliderInputBinding, { 

    find: function(scope) { 
    return $(scope).find(".ui-limitslider"); 
    }, 

    getValue: function(el) { 
    return $(el).limitslider("values"); 
    }, 

    setValue: function(el, values) { 
    $(el).limitslider("values", values); 
    }, 

    subscribe: function(el, callback) { 
    $(el).on("slidechange.limitSliderInputBinding", function(e) { 
     callback(); 
    }); 
    }, 

    unsubscribe: function(el) { 
    $(el).off(".limitSliderInputBinding"); 
    } 

}); 

Shiny.inputBindings.register(limitSliderInputBinding); 

Ich denke, bin aber nicht sicher, dass das Problem irgendwo in der subscribe Eigentum liegt.

Ich benutze jQuery UI v1.11.4. Wenn jemand irgendwelche Tipps oder Vorschläge oder Dinge zu versuchen hat, würde ich die Hilfe begrüßen!

Vielen Dank!

Antwort

1

Ok, einige Kollegen haben mir geholfen, das herauszufinden. Es stellt sich heraus, dass limitslider, das auf jQuery-UI aufbaut, nicht mit einer "change" -Funktion initialisiert wird. Also, diese Korrekturen arbeiten:

$(this).limitslider({ 
    values: [a, c, b], 
    gap: 0, 
    label: true, 
    min: min, 
    max: max, 
    change: function(event, ui){} 
}) 

ich gemacht, dass die Modifikation meiner limitslidershiny.js Datei.

Es stellt sich auch heraus, dass der Ereignistyp, der ausgelöst wird, "limitsliderchange" heißt (Sie können dies unter console.log (event) sehen).

Also, auf dieser Grundlage habe ich diese Änderungen an der Datei limitsliderinputbinding.js:

subscribe: function(el, callback) { 
    $(el).on("limitsliderchange.limitSliderInputBinding", function(e) { 
    callback(); 
    }); 
} 

... und abmelden ähnlich.