我的应用程序中有两个selectizeInputs(state1
和state2
),它们具有相同的选择集。当用户单击actionButton时,我想比较state1
和state2
的值,如果它们相同,则向用户显示一条反馈消息。
两个selectizeInputs均使用占位符“按名称搜索”初始化。如果我是第一次更改一个输入的值,而另一个则保持其占位符的值不变,那么单击操作按钮将触发反馈消息:
这让我感到困惑,因为仅当state1
和state2
相同时才显示该消息。
以下是复制以上代码的代码:
library(shiny)
library(shinyFeedback)
ui <- fluidPage(shinyFeedback::useShinyFeedback(),
selectizeInput('state1', 'Select state 1', choices = state.name,
multiple = T,
options = list(placeholder = "Search by name", maxItems = 1)),
selectizeInput('state2', 'Select state 2', choices = state.name,
multiple = T,
options = list(placeholder = "Search by name", maxItems = 1)),
actionButton("click", "Click"),
textOutput("states")
)
server <- function(input, output, session) {
values = reactiveValues(states = NULL)
observeEvent(input$click, {
feedbackDanger("state1", input$state1 == input$state2, "")
feedbackDanger("state2", input$state2 == input$state1, "State 1 and state 2 cannot be the same.")
req(!is.null(input$state1), !is.null(input$state2), input$state1 != input$state2)
values$states <- paste(input$state1, input$state2)
})
output$states <- renderText({
values$states
})
}
shinyApp(ui, server)
我认为这可能与在selectizeInputs中使用multiple = T和maxItems = 1或我编写触发条件的方式有关,但我不明白为什么它们是错误的。任何帮助将不胜感激。
答案 0 :(得分:3)
该错误已在shinyFeeback
的GitHub版本中得到解决。如果您从GitHub安装软件包,则原始代码应该可以正常工作:
devtools::install_github("merlinoa/shinyFeedback")
-
您正在按照正确的思路进行思考!在第一个示例中,input$state1
是“阿拉斯加”,而input$state2
是空的。 selectizeInput
与multiple = T
的初始值是NULL
。
当您的feedbackDanger
条件比较两个值时,结果为空逻辑:
> "Alaska" == NULL
logical(0)
空逻辑作为空对象传递给shinyFeedback
JavaScript函数checkFeedback
。空对象是truthy,因此“在布尔上下文中遇到true
时也被认为是”。因此,当checkFeedback
评估值时:
if (message.condition) {
....
该语句返回true
,并显示feedbackDanger
消息。
一种简单的解决方案是先检查两个值是否为NULL
,然后检查是否相等,例如:
((!is.null(input$state1) & !is.null(input$state2)) && (input$state1 == input$state2))
编辑::我们使用&&
,以便我们首先评估其中一个值是否为NULL
。仅当两个值都不为NULL
时,我们才评估这些值是否相同。按此顺序进行评估可避免将空逻辑发送给JS函数。有关&
与&&
的更多信息,请参见this answer。 /编辑
完整的解决方案如下:
library(shiny)
library(shinyFeedback)
ui <- fluidPage(shinyFeedback::useShinyFeedback(),
selectizeInput('state1', 'Select state 1', choices = state.name,
multiple = T,
options = list(placeholder = "Search by name", maxItems = 1)),
selectizeInput('state2', 'Select state 2', choices = state.name,
multiple = T,
options = list(placeholder = "Search by name", maxItems = 1)),
actionButton("click", "Click"),
textOutput("states")
)
server <- function(input, output, session) {
values = reactiveValues(states = NULL)
observeEvent(input$click, {
condition <- ((!is.null(input$state1) & !is.null(input$state2)) && (input$state1 == input$state2))
feedbackDanger("state1", condition, "")
feedbackDanger("state2", condition, "State 1 and state 2 cannot be the same.")
req(!is.null(input$state1), !is.null(input$state2), input$state1 != input$state2)
values$states <- paste(input$state1, input$state2)
})
output$states <- renderText({
values$states
})
}
shinyApp(ui, server)