引导日期选取器在选择后返回焦点

Bootstrap datepicker return focus after select

本文关键字:选择 返回 焦点 日期 选取      更新时间:2023-09-26

如果使用 autoclose: true 从 eternicode 初始化引导日期选择器,则会发生两种不良行为:

  1. 选取器关闭后,当您按 Tab 键进入下一个字段时,您将再次从文档的开头开始。 这在长表单上可能非常麻烦。
  2. 由于选取器以编程方式更改值,因此您关心输入上的模糊事件的任何侦听器的行为都将无法正常工作。 当您选择选取器值并且输入的值未更改时,实际上会发生模糊。 然后,引导日期选取器以编程方式更新字段,以便永远不会使用新值触发模糊。

下面是堆栈片段中的演示
*选择任何字段,从选取器中选择一个值,然后点击 Tab

$(".datepicker").datepicker({
  autoclose: true
});
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

根据选择 jQuery UI 日期选取器后焦点字段的答案,您可以点击onCloseonSelect事件,但引导选取器不提供这些事件。

简单地用hide替换它们似乎也不起作用,因为重新聚焦将创建一个无限循环,在您尝试关闭它时始终保持选择器打开。

$(".datepicker").datepicker({
  autoclose: true
})
.on('hide', function () {
  $(this).focus();
});

堆栈代码段演示

$(".datepicker").datepicker({
  autoclose: true
})
.on('hide', function () {
  $(this).focus();
});
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

这是一个有点

黑客工作,但你可以有条件地隐藏和显示元素以避免无限循环。 隐藏时,检查这是否是第一次尝试隐藏。 如果输入没有焦点(意味着他们使用了下拉列表并且我们丢失了 Tab 键顺序),则重新聚焦将导致选取器显示。 我们还将捕捉这个节目并从那里隐藏起来,回到我们的原始代码中。 我们将在对象上来回传递一个属性,以便我们可以管理状态。

这将看起来像这样:

$(".datepicker").datepicker({
  autoclose: true
})
.on('hide', function () {
  if (!this.firstHide) {
    if (!$(this).is(":focus")) {
      this.firstHide = true;
      // this will inadvertently call show (we're trying to hide!)
      this.focus(); 
    }
  } else {
    this.firstHide = false;
  }
})
.on('show', function () {
  if (this.firstHide) {
    // careful, we have an infinite loop!
    $(this).datepicker('hide'); 
  }
})

堆栈代码段演示

$(".datepicker").datepicker({
  autoclose: true
})
.on('hide', function () {
  if (!this.firstHide) {
    if (!$(this).is(":focus")) {
      this.firstHide = true;
      // this will inadvertently call show (we're trying to hide!)
      this.focus(); 
    }
  } else {
    this.firstHide = false;
  }
})
.on('show', function () {
  if (this.firstHide) {
    // careful, we have an infinite loop!
    $(this).datepicker('hide'); 
  }
})
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>

我正在尝试实现同样的事情,但不知何故,解决方案有点问题。例如,如果再次单击同一日期选取器,它将没有响应。如果您多次单击,浏览器将停止响应。我有一个更好的解决方案,如下所示。

我的解决方案是欺骗日期选择器专注于DIV中的下一个元素。我有欧芹验证,它会自动为我添加<UL>

<div>   
<input type="text" class="datepicker" />
<ul class="error-message"></ul>
</div>
$('.datepicker').datepicker({
        autoclose: true
    }).on('hide', function () {
        $(this).next('ul').attr('tabindex',-1).focus();
    });

当前日期 使用@KyleMit解决方案添加的功能

var date = new Date();
  var today = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  var end = new Date(date.getFullYear(), date.getMonth(), date.getDate());
$(".datepicker").datepicker({
  autoclose: true
})
.on('hide', function () {
  if (!this.firstHide) {
    if (!$(this).is(":focus")) {
      this.firstHide = true;
      // this will inadvertently call show (we're trying to hide!)
      this.focus(); 
    }
  } else {
    this.firstHide = false;
  }
})
.on('show', function () {
  if (this.firstHide) {
    // careful, we have an infinite loop!
    $(this).datepicker('hide'); 
  }
})
$('.datepicker').datepicker('setDate', today);
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/css/datepicker.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.3.1/js/bootstrap-datepicker.js"></script>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>
<input type="text" class="datepicker" /><br/>