选择预定义范围时防止 Daterangepicker 关闭
Prevent Daterangepicker from closing when predefined range selected
我正在使用 Dan Grossman 的 DateRangePicker 插件为用户提供一种方法来 select 我网站上特定功能的预定义和自定义日期范围。我有它的工作,但我有一个困扰我的问题,我一直无法解决。
当用户点击预定义的日期范围时,bootstrap 下拉菜单关闭。这导致用户必须重新打开日期选择器并单击 "apply" 按钮才能执行该功能。
我希望下拉菜单在单击预定义的日期范围后保持打开状态。如果用户对范围满意,则可以快速单击应用按钮。
我试过以下方法:
$(function() {
$(document).on('click', '.ranges li', function(e) {
e.preventDefault();
});
});
这有效地阻止了下拉菜单的关闭,但它不会执行 "clickRange" 函数以在适当的输入中设置开始和结束日期。
只需尝试使用此代码,其中 config-demo 是文本框的 ID,您可以替换文本框 ID:
$(function () {
$(document).on('click', '.ranges li', function (e) {
$("#config-demo").focus();
});
});
当您 select 范围不是 "Custom Range" 时,只显示调用 show()
函数。
您可以使用以下代码:
$(function() {
var listItem,applyClicked=false;
/* $(document).on('click', '.ranges li', function(e) {
e.preventDefault();
}); */
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
/* console.log(start.format('MMMM D, YYYY') + ' - '
+ end.format('MMMM D, YYYY')); */
$('#reportrange span').html(
start.format('MMMM D, YYYY') + ' - '
+ end.format('MMMM D, YYYY'));
}
$('#reportrange').daterangepicker(
{
startDate : start,
endDate : end,
ranges : {
'Today' : [ moment(), moment() ],
'Yesterday' : [ moment().subtract(1, 'days'),
moment().subtract(1, 'days') ],
'Last 7 Days' : [ moment().subtract(6, 'days'),
moment() ],
'Last 30 Days' : [ moment().subtract(29, 'days'),
moment() ],
'This Month' : [ moment().startOf('month'),
moment().endOf('month') ],
'Last Month' : [
moment().subtract(1, 'month').startOf('month'),
moment().subtract(1, 'month').endOf('month') ]
}
}, cb);
$(".ranges ul li").click(function() {
listItem = $(this).text();
});
$(".range_inputs ").click(function() {
applyClicked=true;
});
$('#reportrange').on('apply.daterangepicker', function(ev, picker) {
console.log(listItem +" : "+ applyClicked);
if(listItem!="Custom Range" && !applyClicked){
picker.show();
applyClicked=false;
}
//ev.preventDefault();
});
cb(start, end);
});
<!-- Include Required Prerequisites -->
<script type="text/javascript"
src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script>
<script type="text/javascript"
src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<link rel="stylesheet" type="text/css"
href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css" />
<!-- Include Date Range Picker -->
<script type="text/javascript"
src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
<link rel="stylesheet" type="text/css"
href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
<div id="reportrange" class="pull-right"
style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc; width: 100%">
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i> <span></span>
<b class="caret"></b>
</div>
如果您还需要什么,请告诉我。
does not really work except the initial run, as Elijah pointed out in his
这也取决于默认范围选项的文本值。由于它的脆弱性,这是一种糟糕的编程实践。在这种情况下,如果您使用多种语言的小部件,该解决方案 会 失效。
我开发了以下解决方案,想在这里分享;
initDateRangePicker($('input'))
function initDateRangePicker($input) {
$input.daterangepicker({
alwaysShowCalendars: true,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
}
})
$input.on('apply.daterangepicker', function(ev, picker) {
if (rangeClicked) picker.show()
})
let rangeClicked = false
// we want picker to remain open when after selecting a custom range
$('.daterangepicker').not('.custom-events-attached').not('.custom-events-attached')
// mark picker instance(s) as processed, so we won't attach duplicate events in the future
.addClass('custom-events-attached')
// clicking anywhere on the picker will reset our state
// this is not a problem since this click event will always be fired after `apply.daterangepicker`
.click(() => rangeClicked = false)
// selecting one of the ranges will let us know that we want to keep our picker open
// on the next `apply` event
.find('.ranges').find('li').click(() => {
rangeClicked = true
})
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.js"></script>
<input type="text" name="date-range">
我正在使用 Dan Grossman 的 DateRangePicker 插件为用户提供一种方法来 select 我网站上特定功能的预定义和自定义日期范围。我有它的工作,但我有一个困扰我的问题,我一直无法解决。
当用户点击预定义的日期范围时,bootstrap 下拉菜单关闭。这导致用户必须重新打开日期选择器并单击 "apply" 按钮才能执行该功能。
我希望下拉菜单在单击预定义的日期范围后保持打开状态。如果用户对范围满意,则可以快速单击应用按钮。
我试过以下方法:
$(function() {
$(document).on('click', '.ranges li', function(e) {
e.preventDefault();
});
});
这有效地阻止了下拉菜单的关闭,但它不会执行 "clickRange" 函数以在适当的输入中设置开始和结束日期。
只需尝试使用此代码,其中 config-demo 是文本框的 ID,您可以替换文本框 ID:
$(function () {
$(document).on('click', '.ranges li', function (e) {
$("#config-demo").focus();
});
});
当您 select 范围不是 "Custom Range" 时,只显示调用 show()
函数。
您可以使用以下代码:
$(function() {
var listItem,applyClicked=false;
/* $(document).on('click', '.ranges li', function(e) {
e.preventDefault();
}); */
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
/* console.log(start.format('MMMM D, YYYY') + ' - '
+ end.format('MMMM D, YYYY')); */
$('#reportrange span').html(
start.format('MMMM D, YYYY') + ' - '
+ end.format('MMMM D, YYYY'));
}
$('#reportrange').daterangepicker(
{
startDate : start,
endDate : end,
ranges : {
'Today' : [ moment(), moment() ],
'Yesterday' : [ moment().subtract(1, 'days'),
moment().subtract(1, 'days') ],
'Last 7 Days' : [ moment().subtract(6, 'days'),
moment() ],
'Last 30 Days' : [ moment().subtract(29, 'days'),
moment() ],
'This Month' : [ moment().startOf('month'),
moment().endOf('month') ],
'Last Month' : [
moment().subtract(1, 'month').startOf('month'),
moment().subtract(1, 'month').endOf('month') ]
}
}, cb);
$(".ranges ul li").click(function() {
listItem = $(this).text();
});
$(".range_inputs ").click(function() {
applyClicked=true;
});
$('#reportrange').on('apply.daterangepicker', function(ev, picker) {
console.log(listItem +" : "+ applyClicked);
if(listItem!="Custom Range" && !applyClicked){
picker.show();
applyClicked=false;
}
//ev.preventDefault();
});
cb(start, end);
});
<!-- Include Required Prerequisites -->
<script type="text/javascript"
src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script>
<script type="text/javascript"
src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<link rel="stylesheet" type="text/css"
href="//cdn.jsdelivr.net/bootstrap/latest/css/bootstrap.css" />
<!-- Include Date Range Picker -->
<script type="text/javascript"
src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
<link rel="stylesheet" type="text/css"
href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
<div id="reportrange" class="pull-right"
style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc; width: 100%">
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i> <span></span>
<b class="caret"></b>
</div>
如果您还需要什么,请告诉我。
这也取决于默认范围选项的文本值。由于它的脆弱性,这是一种糟糕的编程实践。在这种情况下,如果您使用多种语言的小部件,该解决方案 会 失效。
我开发了以下解决方案,想在这里分享;
initDateRangePicker($('input'))
function initDateRangePicker($input) {
$input.daterangepicker({
alwaysShowCalendars: true,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
}
})
$input.on('apply.daterangepicker', function(ev, picker) {
if (rangeClicked) picker.show()
})
let rangeClicked = false
// we want picker to remain open when after selecting a custom range
$('.daterangepicker').not('.custom-events-attached').not('.custom-events-attached')
// mark picker instance(s) as processed, so we won't attach duplicate events in the future
.addClass('custom-events-attached')
// clicking anywhere on the picker will reset our state
// this is not a problem since this click event will always be fired after `apply.daterangepicker`
.click(() => rangeClicked = false)
// selecting one of the ranges will let us know that we want to keep our picker open
// on the next `apply` event
.find('.ranges').find('li').click(() => {
rangeClicked = true
})
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.js"></script>
<input type="text" name="date-range">