Bootstrap 日期选择器 return 焦点在 select 之后
Bootstrap datepicker return focus after select
如果用 autoclose: true
初始化 bootstrap datepicker from eternicode,会发生两种不良行为:
- 选择器关闭后,当您切换到下一个字段时,您将再次从文档的开头开始。这在长表单上可能非常麻烦。
- 因为选择器以编程方式更改值,所以您拥有的任何关心输入上的模糊事件的侦听器都不会正常运行。当您 select 选择器值和输入值未更改时,实际上会发生模糊。然后 bootstrap-datepicker 以编程方式更新字段,因此永远不会用新值触发模糊。
这是堆栈片段中的演示:
*select 任何字段,select 来自选择器的值,然后点击 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/>
根据Focus the field after selecting the jQuery UI datepicker, you can tap into the onClose
or onSelect
events, but the bootstrap picker doesn't offer those events的回答。
简单地用 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/>
这有点像 hack 工作,但您可以有条件地隐藏和显示元素以避免无限循环。在隐藏时,检查这是否是第一次尝试隐藏。如果输入没有焦点(意味着他们已经使用了下拉菜单并且我们已经丢失了我们的 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/>
如果用 autoclose: true
初始化 bootstrap datepicker from eternicode,会发生两种不良行为:
- 选择器关闭后,当您切换到下一个字段时,您将再次从文档的开头开始。这在长表单上可能非常麻烦。
- 因为选择器以编程方式更改值,所以您拥有的任何关心输入上的模糊事件的侦听器都不会正常运行。当您 select 选择器值和输入值未更改时,实际上会发生模糊。然后 bootstrap-datepicker 以编程方式更新字段,因此永远不会用新值触发模糊。
这是堆栈片段中的演示:
*select 任何字段,select 来自选择器的值,然后点击 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/>
根据Focus the field after selecting the jQuery UI datepicker, you can tap into the onClose
or onSelect
events, but the bootstrap picker doesn't offer those events的回答。
简单地用 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/>
这有点像 hack 工作,但您可以有条件地隐藏和显示元素以避免无限循环。在隐藏时,检查这是否是第一次尝试隐藏。如果输入没有焦点(意味着他们已经使用了下拉菜单并且我们已经丢失了我们的 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/>