【问题标题】:Autoclose date range input shiny自动关闭日期范围输入闪亮
【发布时间】:2018-08-29 13:54:03
【问题描述】:

我希望日期选择器在选择日期后自动关闭。当 daterangeinput 直接在 ui 中呈现时,我知道该怎么做,但在服务器中创建时不知道。

这是我的代码。

library('shiny')

js_string <- "$('#dates input').bsDatepicker({autoclose: true});"

shinyApp(
  ui = fluidPage(
    tags$head(tags$script(HTML('Shiny.addCustomMessageHandler("jsCode", function(message) { eval(message.value); });'))),
    includeScript("code.js"),
    fluidRow(
      column(4, 
             uiOutput(outputId = 'dateui'),
             verbatimTextOutput("datesOut")
      )
    )
  ), 
  server = function(input, output, session) {
    output$dateui <- renderUI({
      dateRangeInput("dates", label = h3("Date range"))
    })
    session$onFlushed(function() {
      session$sendCustomMessage(type = 'jsCode', list(value = js_string))
    })
    output$datesOut <- renderPrint({ names(session) })
  }
)

$('#dates input').bsDatepicker({autoclose: true}); 如果直接在 ui 中创建日期范围,则效果很好,如下面的代码所示。此外,如果我想用$('#dates').attr('onkeydown', 'return false'); 禁用键盘输入,这段代码也很有效。

library('shiny')

shinyApp(
  ui = fluidPage(
    includeScript("code.js"),
    fluidRow(
      column(4, 
             dateRangeInput("dates", label = h3("Date range")),
             verbatimTextOutput("datesOut")
      )
    )
  ), 
  server = function(input, output, session) {
    output$datesOut <- renderPrint({ input$dates })
  }
)

加上js代码

$(document).ready(function(){
  $('#dates input').bsDatepicker({autoclose: true});
});

我的问题与我发布的another question 有关。

我也试过$('#dates input').datepicker({autoclose: true});,但它不起作用。我知道$(document).ready(function() ... 不能工作,因为一旦文档准备好,代码就会在渲染日期范围之前启动。

编辑:

我也尝试过使用shinyjs,但它也不起作用。

library('shiny')
library('shinyjs')

jsCode <- "shinyjs.changeDate = function(){
$('#dates input').bsDatepicker({autoclose: true});
$('#dates').attr('onkeydown', 'return false');
}"

shinyApp(
  ui = fluidPage(
    useShinyjs(),
    extendShinyjs(text = jsCode),
    fluidRow(
      column(4, 
             uiOutput(outputId = 'dateui'),
             verbatimTextOutput("datesOut")
      )
    )
  ),
  server = function(input, output, session) {
    output$dateui <- renderUI({
      dateRangeInput("dates", label = h3("Date range"))
    })
    session$onFlushed(function() {
      js$changeDate()
    })
  }
)

我被困在这里,非常感谢任何帮助。

干杯

Edit2:添加我的会话信息

R version 3.4.4 (2018-03-15)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.3

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shinyjs_1.0 shiny_1.0.5 V8_1.5     

loaded via a namespace (and not attached):
 [1] compiler_3.4.4  R6_2.2.2        htmltools_0.3.6 tools_3.4.4     curl_3.1       
 [6] yaml_2.1.18     Rcpp_0.12.16    digest_0.6.15   jsonlite_1.5    xtable_1.8-2   
[11] httpuv_1.3.6.2  mime_0.5 

【问题讨论】:

  • 也许你应该试试shinyjs的包hide()
  • 使用shinyjs::hide() 我可以隐藏日期范围输入,但不只是日期选择器,而无需添加不起作用的.datepicker()
  • 我没有用过js字符串,所以我想我不知道。
  • 我真的卡住了,我不明白为什么我的代码在使用Shiny.addCustomMessageHandler 调用时没有相同的效果。我想我必须深入研究 js 和 Shiny 之间的联系。

标签: javascript r shiny shinyjs


【解决方案1】:

这有点 hacky,但它可以使用 JQuery:

            tags$head(
                tags$script(HTML("setInterval(
                      function checkContainer () {
                        if($('.datepicker-days').is(':visible')){ //if the container is visible on the page
                          $(function () {
                              $('td.day').click(function () {
                                $('.dropdown-menu').hide()
                              }); 
                            });
                          } else {
                            setTimeout(checkContainer, 50); //wait 50 ms, then try again
                          }
                        },
                      50  /* 10000 ms = 10 sec */
                      );"))
            )

您需要做的就是将其添加到您的uifluidpage 内的tags$head 函数中。

如果最后一个用户输入是选择日期,则此方法有效。

如果您的dateRangeInput 仅限于选择月份,那么您只需将'.datepicker-days' 编辑为'.datepicker-months' 并将'.td.day' 更改为'.td.month'。如果您限制为一年;将days 更改为years 并将day 更改为year

为什么它是 hacky 的原因是因为 JQuery 脚本每 50 毫秒重新部署一次,以检查 datepicker-days 类是否可见......但它可以工作。

【讨论】:

    猜你喜欢
    • 2014-05-15
    • 2019-05-13
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    相关资源
    最近更新 更多