在 RShiny 的数据表的第二页中禁用 selectizeInput

Posted

技术标签:

【中文标题】在 RShiny 的数据表的第二页中禁用 selectizeInput【英文标题】:Disabling selectizeInput in second page of datatable in RShiny 【发布时间】:2021-11-01 17:05:39 【问题描述】:

我有一个数据表,其中嵌入了 selectizeInputs。我使用 jquery 来启用 selectizeInputs 中的一些选项(例如创建选项)。

现在,由于业务用例,我想禁用一些 selectizeInputs(通过某些条件动态选择)。这些输入也可能位于数据表的第 2、3、.. n 页。

但是,我只能禁用第一页上的输入,而不能禁用后续页面上的输入。我附上了一个最小且可重复的示例,如果有人可以帮助我,那就太好了。

library(shiny)
library(DT)

ui <- fluidPage(
  shinyjs::useShinyjs(),
  selectizeInput(
    inputId = "input",
    label = "",
    choices = letters[1:26],
    selected = letters[1]
  ),
  
  fluidRow(
    DTOutput(outputId = "table"),
    tags$script(html("Shiny.addCustomMessageHandler('unbind-DT', function(id) 
                                       Shiny.unbindAll($('#'+id).find('table').DataTable().table().node());
                                     )"))
  )
  
)

df <- data.frame('a' = c(1,2), 'sel_input' = NA)
df[1,'sel_input'] <- as.character(
  selectizeInput(inputId = 'mselect', choices=c('car','cars','dog'),
                 label=NULL, selected=NULL))
df[2,'sel_input'] <- as.character(
  selectizeInput(inputId = 'nselect', choices=c('lambo','audi','merc'),
                 label=NULL, selected=NULL))


js <- c(
  "function()Shiny.bindAll(this.api().table().node());",
  "  $('#mselect').selectize(
                           delimiter: \',\',
                           persist: false,
                           create: function(input) 
                              return 
                                 value: input,
                                 text: input
                              
                           
                            );",
  "$('#nselect').selectize(
                           delimiter: \',\',
                           persist: false,
                           create: function(input) 
                              return 
                                 value: input,
                                 text: input
                              
                           
                            );",
  "$('#mselect')[0].selectize.enable()",
  "$('#nselect')[0].selectize.disable()",
  ""
)

server <- function(input, output, session) 
  
  observe(
    print(input$mselect)
  )
  session$sendCustomMessage('unbind-DT', 'table')
  output$table <- renderDT(
    datatable(
      data = df,
      escape = FALSE,
      options = list(
        dom='tp',
        pageLength=1,
        processing=F,
        preDrawCallback = JS('function()Shiny.unbindAll(this.api().table().node());'),
        drawCallback = JS(js)
      )
    )
    
  )
  


shinyApp(ui = ui, server = server)

【问题讨论】:

@RonakShah 你现在可以试试吗?抱歉,代码中存在错误。数据表中基本上有 2 页。我希望能够禁用第二页中的下拉菜单。 大家好,对此问题有任何回应或评论吗?积极寻找解决方案。如果需要更多内容,请告诉我,我会提供。 【参考方案1】:

所以,我能够自己解决它。基本上这里的问题不是基于 R/Rshiny。这实际上是我忽略的代码中的一个 javascript 错误。

当您进行分页时,仅当前(选定)页面中的元素是 DOM 的一部分。所有其他都被删除/未创建。在上面的代码中,在 drawCallback 中(这是每次需要重新渲染数据表时运行的一段代码)我正在为所有元素发出命令,无论它们是否存在于 DOM 中。因此,javascript 代码会失败,并且不会发生禁用/启用。

这里的解决方案是首先检查一个元素在 DOM 中是否处于活动状态,然后才发出启用/禁用命令。

因此,本质上,将上述命令包含在 if else 语句中

if ($('#mselect').length > 0)
$('#mselect').selectize()[0].selectize.enable();


if ($('#nselect').length > 0)
$('#nselect').selectize()[0].selectize.disable();

这样,只有当特定元素存在于 DOM 中时,javascript 代码才会运行,然后您就可以在分页数据表的第二页中实现禁用 selectInput。

【讨论】:

以上是关于在 RShiny 的数据表的第二页中禁用 selectizeInput的主要内容,如果未能解决你的问题,请参考以下文章

如何在分页中查看第二页

数据表工具提示在第二页中不起作用。仅适用于第一页

关于criteria分页中获取总记录数异常问题

如何处理thinkphp很多分页中:比如我现在要点击第二页修改数据,修改完了仍然返回二页,而不是第一页,

如何在第二页中使用 localStorage 显示第一页的内容

点击第二页中的滚动视图时滚动到第一页