使用choiceNames/choiceValues时shinyjs::disable失效问题咨询
解决Shiny中同时修改复选框字体颜色并禁用的问题
问题根源
当用updateCheckboxGroupInput的choiceNames重新渲染复选框组时,原来的DOM元素会被完全替换,导致之前调用shinyjs::disable选中的元素已经不存在,自然没法生效。核心是要等DOM更新完成后再执行禁用操作,或者直接在渲染元素时就加上禁用属性。
两种可行方案
方案一:延迟执行禁用操作
在updateCheckboxGroupInput之后,用shinyjs::delay给DOM一点更新时间,再执行禁用。修改后的服务器代码如下:
server <- function(input, output, session) { observe({ if(input$options1 == "Don't allow B"){ updateCheckboxGroupInput(session, inputId = "options2", label = "", choiceNames = list( tags$span("A"), tags$span("B", style = "color: grey;") ), choiceValues = c("a", "b"), selected = input$options2[input$options2 != 'b'], inline = TRUE) # 延迟100毫秒执行禁用,确保DOM已更新 shinyjs::delay(100, shinyjs::disable(selector = "#options2 input[value='b']")) } else { updateCheckboxGroupInput(session, inputId = "options2", choices = c("A" = "a", "B" = "b"), selected = input$options2, inline = TRUE) shinyjs::enable(selector = "#options2 input[value='b']") } }) }
方案二:直接在渲染时添加禁用属性和样式
不需要依赖shinyjs的disable,直接在choiceNames里构建带disabled属性的复选框元素,同时设置灰色字体。代码如下:
server <- function(input, output, session) { observe({ if(input$options1 == "Don't allow B"){ # 先移除B的选中状态 new_selected <- input$options2[input$options2 != 'b'] updateCheckboxGroupInput(session, inputId = "options2", label = "", choiceNames = list( tags$span("A"), tags$span( tags$input(type = "checkbox", value = "b", disabled = "disabled"), tags$label("B", style = "color: grey;") ) ), choiceValues = c("a", "b"), selected = new_selected, inline = TRUE) } else { updateCheckboxGroupInput(session, inputId = "options2", choices = c("A" = "a", "B" = "b"), selected = input$options2, inline = TRUE) } }) }
注意点
- 方案一的延迟时间可以根据实际情况调整,100毫秒足够应对大多数场景;
- 方案二更直接,避免了DOM更新时机的问题,不需要额外依赖shinyjs的延迟函数。
内容的提问来源于stack exchange,提问作者Anke
相关产品推荐
相关产品推荐

