在 R Shiny 的数据表的第二页中禁用 selectinput
Disabling selectizeInput in second page of datatable in RShiny
我有一个数据表,其中嵌入了 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)
所以,我能够自己解决它。基本上这里的问题不是基于R/Rshiny。这实际上是我忽略的代码中的一个 javascript 错误。
当您进行分页时,只有当前(选定)页面中的元素是 DOM 的一部分。所有其他人都是 removed/not 创建的。在上面的代码中,在 drawCallback 中(这是每次需要重新渲染数据表时 运行s 的代码)我正在为所有元素发出命令,无论它们是否存在于 DOM 还是不行。因此,javascript 代码失败并且 disabling/enabling 不会发生。
这里的解决方案是首先检查 DOM 中的元素是否处于活动状态,然后才发出 enabling/disabling 命令。
因此,本质上,将上述命令包含在 if else 语句中
if ($('#mselect').length > 0){
$('#mselect').selectize()[0].selectize.enable();
}
if ($('#nselect').length > 0){
$('#nselect').selectize()[0].selectize.disable();
}
这样 javascript 代码只会 运行 当特定元素存在于 DOM 中时,然后您就可以在分页数据表的第二页中实现禁用 selectInput。
我有一个数据表,其中嵌入了 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)
所以,我能够自己解决它。基本上这里的问题不是基于R/Rshiny。这实际上是我忽略的代码中的一个 javascript 错误。
当您进行分页时,只有当前(选定)页面中的元素是 DOM 的一部分。所有其他人都是 removed/not 创建的。在上面的代码中,在 drawCallback 中(这是每次需要重新渲染数据表时 运行s 的代码)我正在为所有元素发出命令,无论它们是否存在于 DOM 还是不行。因此,javascript 代码失败并且 disabling/enabling 不会发生。
这里的解决方案是首先检查 DOM 中的元素是否处于活动状态,然后才发出 enabling/disabling 命令。
因此,本质上,将上述命令包含在 if else 语句中
if ($('#mselect').length > 0){
$('#mselect').selectize()[0].selectize.enable();
}
if ($('#nselect').length > 0){
$('#nselect').selectize()[0].selectize.disable();
}
这样 javascript 代码只会 运行 当特定元素存在于 DOM 中时,然后您就可以在分页数据表的第二页中实现禁用 selectInput。