限制所选滑块输入之间的间隔

Limit interval between selected slider inputs

给定一个 sliderInput,我希望能够根据 selection 之间的长度(范围)限制用户可以 select 的可能值。例如,给定一个 sliderInput 可能的值 1:100,我想允许用户 select 任何范围,前提是第一个和最后一个之间的差异小于 5。

以下未按预期工作

library(shiny)
ui <- fluidPage(
  sliderInput(
    "test_slider",
    "Test Me",
    value = c(1,2),
    min = 1,
    max = 100,
    step = 1
  ),
  textOutput("what_selected")
)

server <- function(input, output, session){
  observe({
    selected <- req(input$test_slider[1]):req(input$test_slider[2])

    
  
output$what_selected <- renderText(
  if(all(length(selected)>1,max(selected)-min(selected) > 5)){
    
    print("You selected a range that is greater than 5,
            choosing the first five")
    selected <- selected[1:5]
    
  }
  selected)
   
    
  })
}



shinyApp(ui, server)


我看过 which seems close but different to what I need. 看起来最接近但还是有点不同。

这个问题中的示例有点过于简单,但我认为它足以重现。

编辑

问题是我不确定如何在不将滑块重置为 1:5 的情况下将范围限制为 1-5。例如,如果我 select 1-20,我需要将滑块设置回 1:5。另外,如果例如我 select 50:60,我需要 select 50-55 等等。一个选项是在服务器中执行此操作,但我希望用户看到更改。

以下按预期工作。但是,用户不会立即知道在服务器端,我们只 selected 了前五个。我很想将范围重置为新的 selected 值,并在“抱歉,只能 select 范围内的前五个值”下方显示一条消息。

我想我理解你的问题,但我不确定你想要的解决方法:

您不想限制选择。 您不希望只更新服务器端的滑块,而不让用户注意到发生了什么,对吗?

那么我唯一能想到的就是{shinyFeedback}。只使用前五个值,如果最小值和最大值之间的范围大于五个,请告知用户,但不要更改滑块。

这是解决问题的方法吗?

library(shiny)
library(shinyFeedback)

shinyApp(ui = fluidPage(
  
  useShinyFeedback(), # include shinyFeedback
  
  br(),
  
  sliderInput(
    "test_slider",
    "Test Me",
    value = c(1,2),
    min = 1,
    max = 100,
    step = 1
  ),
  
  verbatimTextOutput(outputId = "result")
  
  ),
  
  server = function(input, output, session) {
    
    r <- reactiveValues(slider = NULL)
    
    observeEvent(input$test_slider, {
      
      if (input$test_slider[2] - input$test_slider[1] >= 5) {
        
        
        showFeedbackWarning(
          inputId = "test_slider",
          text = "Only the first five values will be selected."
        )
      
        r$slider <- input$test_slider[1] + c(0:4)
        
      } else {
        
        hideFeedback("test_slider")
        
        r$slider <- c(input$test_slider[1]:input$test_slider[2])
          
      }
      
    })
    
    output$result <- renderPrint(r$slider)
    
  })