R Shiny-如果两个输入具有相同的值,则如何显示反馈消息(使用ShinyFeedback)

时间:2019-02-06 23:09:36

标签: r validation shiny

我的应用程序中有两个selectizeInputs(state1state2),它们具有相同的选择集。当用户单击actionButton时,我想比较state1state2的值,如果它们相同,则向用户显示一条反馈消息。

两个selectizeInputs均使用占位符“按名称搜索”初始化。如果我是第一次更改一个输入的值,而另一个则保持其占位符的值不变,那么单击操作按钮将触发反馈消息:

enter image description here enter image description here

这让我感到困惑,因为仅当state1state2相同时才显示该消息。

以下是复制以上代码的代码:

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或我编写触发条件的方式有关,但我不明白为什么它们是错误的。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

编辑:2019-02-13

该错误已在shinyFeeback的GitHub版本中得到解决。如果您从GitHub安装软件包,则原始代码应该可以正常工作:

devtools::install_github("merlinoa/shinyFeedback")

-

问题

您正在按照正确的思路进行思考!在第一个示例中,input$state1是“阿拉斯加”,而input$state2是空的。 selectizeInputmultiple = 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)