Jor*_*eys 3 drag-and-drop r shiny
在很多网站上,您都有一个拖放界面来更改列表中元素的顺序.我正在寻找类似Shiny的东西.我希望用户能够拖放列表的元素以通过更改顺序来更改优先级.
现在我有一个滥用的解决方案selectizeInput().这有效,但当选择列表变大时,它很快变得很麻烦.
举例说明:
library(shiny)
shinyApp(
ui = shinyUI({
fluidPage(
title = "Example for ordering objects",
sidebarLayout(
sidebarPanel(uiOutput("selection"),
actionButton('update',"Update")),
mainPanel(
helpText('The order of elements'),
tableOutput('theorder')
)
)
)
}),
server = function(input, output, session) {
values <- reactiveValues(x = c('Item1','Item2','Item3'))
output$selection <- renderUI({
selectizeInput('neworder',
'Select new order',
choices = values$x,
multiple = TRUE)
})
output$theorder <- renderTable(
values$x
)
observeEvent(input$update,{
id <- values$x %in% input$neworder
values$x <- c(input$neworder, values$x[!id])
})
}
)
Run Code Online (Sandbox Code Playgroud)
缺点:要更改列表末尾的顺序,用户必须以正确的顺序选择整个列表.一个错误,他必须重新开始.
愿望清单:一个闪亮的小部件(可能来自另一个包),最好是拖放,这可以使这种动作更方便.
您可以使用自定义输入对象来执行此操作.有一堆库要做到这一点,这里是用一个例子这一个.
以下是javascript中的闪亮绑定代码,需要包含在www您应用的文件夹中:
sortableList.js
var sortableListBinding = new Shiny.InputBinding();
$.extend(sortableListBinding, {
find: function(scope) {
return $(scope).find(".sortableList");
},
getValue: function(el) {
if (typeof Sortable.active != 'undefined'){
return Sortable.active.toArray();
}
else return "";
},
subscribe: function(el, callback) {
$(el).on("change.sortableListBinding", function(e) {
callback();
});
},
unsubscribe: function(el) {
$(el).off(".sortableListBinding");
},
initialize: function(el) {
Sortable.create(el,{
onUpdate: function (evt) {
$(el).trigger("change");
}});
}
});
Shiny.inputBindings.register(sortableListBinding);
Run Code Online (Sandbox Code Playgroud)
它非常小,它在初始化时创建Sortable实例,并在用户使用onUpdate库事件更改元素时返回元素的顺序.
这是一个带有R代码的示例应用程序来创建元素:
app.R
library(shiny)
library(htmlwidgets)
sortableList <- function(inputId, value) {
tagList(
singleton(tags$head(tags$script(src="http://rubaxa.github.io/Sortable/Sortable.js"))),
singleton(tags$head(tags$script(src = "sortableList.js"))),
tags$div(id = inputId,class = "sortableList list-group",
tagList(sapply(value,function(x){
tags$div(class="list-group-item","data-id"=x,x)
},simplify = F)))
)
}
ui <- fluidPage(
sortableList('sortable_list',c(2,3,4)),
sortableList('sortable_list2',c(5,6,7)),
textOutput('test'),
textOutput('test2')
)
server <- function(input, output, session)
{
output$test <- renderText({input$sortable_list})
output$test2 <- renderText({input$sortable_list2})
}
shinyApp(ui=ui, server=server)
Run Code Online (Sandbox Code Playgroud)
该sortableList函数包括Sortable库和sortableList.js带有Shiny绑定代码的函数,并创建包含传递给的向量值的div value.
我的app目录如下:
<application-dir>
|-- www
|-- sortableList.js
|-- app.R
Run Code Online (Sandbox Code Playgroud)
我用它runApp("application-dir")来启动应用程序.