【发布时间】:2022-01-22 03:59:09
【问题描述】:
基于找到的非常有用的复制示例here,我在我的 DT 表的每一列中添加了一个下拉列表。
但是,我正在寻找一种方法来使用来自另一个数据框的值填充这些下拉列表,该数据框与 DT 表中使用的列名称相同。
我尝试使用 input$dtable_columns_selected 对第二个数据帧(此处为“iris2”)进行子集化,但我认为我在这里遗漏了一些东西......
我的尝试:
library(shiny)
library(DT)
Sepal.Length <- c(10,11,12,13,14)
Sepal.Width <- c(1,2,3,4,5)
Petal.Length <- c(10,11,12,13,14)
Petal.Width <- c(1,2,3,4,5)
Species <- c("SpeciesA", "SpeciesB","SpeciesC", "SpeciesD", "SpeciesE")
iris2 <- data.frame(Sepal.Length, Sepal.Width,Petal.Length,Petal.Width)
callback <- c(
"var id = $(table.table().node()).closest('.datatables').attr('id');",
"$.contextMenu({",
" selector: '#' + id + ' td.factor input[type=text]',",
" trigger: 'hover',",
" build: function($trigger, e){",
" var levels = $trigger.parent().data('levels');",
" if(levels === undefined){",
" var colindex = table.cell($trigger.parent()[0]).index().column;",
" levels = table.column(colindex).data().unique();",
" }",
" var options = levels.reduce(function(result, item, index, array){",
" result[index] = item;",
" return result;",
" }, {});",
" return {",
" autoHide: true,",
" items: {",
" dropdown: {",
" name: 'Edit',",
" type: 'select',",
" options: options,",
" selected: 0",
" }",
" },",
" events: {",
" show: function(opts){",
" opts.$trigger.off('blur');",
" },",
" hide: function(opts){",
" var $this = this;",
" var data = $.contextMenu.getInputValues(opts, $this.data());",
" var $input = opts.$trigger;",
" $input.val(options[data.dropdown]);",
" $input.trigger('change');",
" }",
" }",
" };",
" }",
"});"
)
createdCell <- function(levels){
if(missing(levels)){
return("function(td, cellData, rowData, rowIndex, colIndex){}")
}
quotedLevels <- toString(sprintf("\"%s\"", levels))
c(
"function(td, cellData, rowData, rowIndex, colIndex){",
sprintf(" $(td).attr('data-levels', '[%s]');", quotedLevels),
"}"
)
}
ui <- fluidPage(
tags$head(
tags$link(
rel = "stylesheet",
href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.css"
),
tags$script(
src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js"
)
),
DTOutput("dtable")
)
server <- function(input, output){
output[["dtable"]] <- renderDT({
datatable(
iris, editable = "cell", callback = JS(callback),
options = list(
columnDefs = list(
list(
targets = "_all",
className = "factor",
createdCell = JS(createdCell(c(levels(iris2[,input$dtable_columns_selected]))))
)
)
)
)
}, server = FALSE)
}
shinyApp(ui, server)
【问题讨论】:
-
感谢 ismirsehregal 的回复!但是我的 dt 表有 25 列,我不明白这些帖子中提供的脚本如何允许使用另一个数据框的值填充下拉列表。你能帮我多一点,让我走上正轨吗?
-
不确定这是否是有意的,但
selectizeInput方法在这里不起作用,因为当前显示的选择需要在选项中可用(您的示例数据不符合此限制)。例如。这个:selectizeInput("test", "test", choices = 1:10, selected = 12)不起作用。