Shiny DT Datatable可编辑模式:如何同时限制特定列与行的编辑权限?
解决Shiny DT中同时限制行和列编辑的问题
我来帮你搞定这个问题~你之前的代码里没法限制前5行编辑,是因为当editable的target设为'column'时,DT只支持列级别的禁用设置,disable里的rows参数不会生效。要同时实现行和列的编辑限制,有两种比较直接的方案:
方案一:单元格级别的精确控制(推荐)
切换到target='cell'模式,这样可以精确指定哪些单元格不能编辑。我们用expand.grid生成所有需要禁用的单元格坐标,合并后传入disable参数:
library(shiny) library(DT) shinyApp( ui = fluidPage(DTOutput('tbl')), server = function(input, output) { output$tbl = renderDT( datatable( data = iris, options = list(lengthChange = FALSE), editable = list( target = 'cell', # 启用单元格级别的编辑控制 disable = list( cells = rbind( # 禁止第1-5行的所有列编辑 expand.grid(rows = 1:5, columns = 1:ncol(iris)), # 禁止第6行及以后的第1-3列编辑 expand.grid(rows = 6:nrow(iris), columns = 1:3) ) ) ) ) ) } )
这样设置后:
- 第1-5行的所有单元格都不能编辑
- 第6行及以后的第1-3列也不能编辑
- 只有第6行及以后的第4、5列(也就是
Petal.Width和Species)可以正常编辑
方案二:用JavaScript回调补充行级限制
如果你更习惯保留列级别的设置逻辑,也可以通过JS回调给指定行添加不可编辑的样式,阻止编辑事件触发:
library(shiny) library(DT) shinyApp( ui = fluidPage(DTOutput('tbl')), server = function(input, output) { output$tbl = renderDT( datatable( data = iris, options = list(lengthChange = FALSE), editable = list(target = 'column', disable = list(columns = 1:3)), callback = JS( // 初始化时给前5行(JS索引从0开始,对应R的1-5行)添加不可编辑类 "table.on('preInit.dt', function() {", " table.rows([0,1,2,3,4]).nodes().to$().addClass('not-editable');", "});", // 阻止不可编辑行的单元格点击事件,避免触发编辑 "$(document).on('click', '.not-editable td', function(e) {", " e.stopPropagation();", "});" ) ) ) } )
这里要注意:DT在JavaScript中的行索引是从0开始的,所以rows([0,1,2,3,4])对应R代码里的第1到5行。
内容的提问来源于stack exchange,提问作者JulietteC
相关产品推荐
相关产品推荐

