jQuery datepicker- 2 个输入/文本框和限制范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/330737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 08:57:58  来源:igfitidea点击:

jQuery datepicker- 2 inputs/textboxes and restricting range

jqueryjquery-pluginsdatepickerjquery-ui-datepicker

提问by Russ Cam

I am using the jQuery Datepicker widget with two input boxes, one for the "From"date and the second with the "To"date. I am using the jQuery Datepicker functional demoas a basis for getting the two input boxes to work with each other, but I need to be able to add these additional restrictions:

我正在使用带有两个输入框的 jQuery Datepicker 小部件,一个用于“From”日期,第二个用于“To”日期。我使用jQuery Datepicker 功能演示作为让两个输入框相互配合的基础,但我需要能够添加这些额外的限制:

  1. Date range can be no earlier than 01 December 2008

  2. "To"date can be no later than today

  3. Once a "From"date is selected, the "To"date can only be within a range of 7 days after the "From"date

  4. If a "To"date is selected first, then the "From"date can only be within the range of 7 days before the "To"date (with the limit of 01 December being the first selectable date)

  1. 日期范围不能早于 2008 年 12 月 1 日

  2. 截止日期不能晚于今天

  3. 一旦一个“从”被选择的日期,则“到”日期只能是后一个范围在7天之内的“从”日期

  4. 如果首先选择“To”日期,则“From”日期只能在“To”日期之前的 7 天范围内(以 12 月 1 日为第一个可选日期的限制)

I can't seem to get all of the above working together.

我似乎无法让上述所有工作一起工作。

In summary, I would like to be able to select a range of up to 7 days between 01 December and today (I realise I am posting this on 1st December so will only get today for the moment).

总之,我希望能够在 12 月 1 日到今天之间选择最多 7 天的范围(我意识到我是在 12 月 1 日发布的,所以暂时只能到今天)。

My code so far

到目前为止我的代码

$(function () {

$('#txtStartDate, #txtEndDate').datepicker(
            {
            showOn: "both",
            beforeShow: customRange,
            dateFormat: "dd M yy",
            firstDay: 1, 
            changeFirstDay: false
            });
});

function customRange(input) 
{ 

return {
         minDate: (input.id == "txtStartDate" ? new Date(2008, 12 - 1, 1) : null),
         minDate: (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate") : null), 
         maxDate: (input.id == "txtStartDate" ? $("#txtEndDate").datepicker("getDate") : null)
       }; 
}

I'm missing the 7 day range restriction and also preventing a "To"date selection before 01 December 2008 or after today. Any help would be much appreciated, Thanks.

我错过了 7 天范围限制,并且还阻止了2008 年 12 月 1 日之前或今天之后的截止日期选择。任何帮助将不胜感激,谢谢。

采纳答案by Russ Cam

Many thanks for your help Ben, I have built upon your posts and have come up with this. It is now complete and works brilliantly!

非常感谢您的帮助 Ben,我已经建立了您的帖子并提出了这一点。它现在已经完成并且运行良好!

Here's a Working Demo. Add /editto the URL to see the code

这是一个工作演示。将/edit添加到 URL 以查看代码

Complete Code below-

完整代码如下-

$(function () 
{   
    $('#txtStartDate, #txtEndDate').datepicker({
        showOn: "both",
        beforeShow: customRange,
        dateFormat: "dd M yy",
        firstDay: 1, 
        changeFirstDay: false
    });

});

function customRange(input) { 
    var min = new Date(2008, 11 - 1, 1), //Set this to your absolute minimum date
        dateMin = min,
        dateMax = null,
        dayRange = 6; // Set this to the range of days you want to restrict to

    if (input.id === "txtStartDate") {
        if ($("#txtEndDate").datepicker("getDate") != null) {
            dateMax = $("#txtEndDate").datepicker("getDate");
            dateMin = $("#txtEndDate").datepicker("getDate");
            dateMin.setDate(dateMin.getDate() - dayRange);
            if (dateMin < min) {
                dateMin = min;
            }
        }
        else {
            dateMax = new Date; //Set this to your absolute maximum date
        }                      
    }
    else if (input.id === "txtEndDate") {
        dateMax = new Date; //Set this to your absolute maximum date
        if ($("#txtStartDate").datepicker("getDate") != null) {
            dateMin = $("#txtStartDate").datepicker("getDate");
            var rangeMax = new Date(dateMin.getFullYear(), dateMin.getMonth(),dateMin.getDate() + dayRange);

            if(rangeMax < dateMax) {
                dateMax = rangeMax; 
            }
        }
    }
    return {
        minDate: dateMin, 
        maxDate: dateMax
    };     
}

回答by Robin Duckett

I realise I'm a little late to the party, but here is how I modified the working example code. I didn't need to set a specific maximum and minimum date, just didn't want a date range overlap, so I just let them set each other:

我意识到我参加聚会有点晚了,但这是我修改工作示例代码的方式。我不需要设置特定的最大和最小日期,只是不想日期范围重叠,所以我只是让它们相互设置:

jQuery(function() {
  jQuery('#calendardatetime_required_to, #calendardatetime_required_from').datepicker('option', {
    beforeShow: customRange
  });
});

function customRange(input) {
  if (input.id == 'calendardatetime_required_to') {
    return {
      minDate: jQuery('#calendardatetime_required_from').datepicker("getDate")
    };
  } else if (input.id == 'calendardatetime_required_from') {
    return {
      maxDate: jQuery('#calendardatetime_required_to').datepicker("getDate")
    };
  }
}

(My datepickers were already initialised in a script further up, but it's just default settings.)

(我的日期选择器已经在脚本中进一步初始化,但这只是默认设置。)

Seems to do what I need it to :)

似乎做我需要它做的:)

See herefor my example.

请参阅此处了解我的示例。

回答by Ben Koehler

Alright, how about this:

好吧,这个怎么样:

function customRange(input) 
{ 
    var min = new Date(2008, 12 - 1, 1);
    var dateMin = min;
    var dateMax = null;

    if (input.id == "txtStartDate" && $("#txtEndDate").datepicker("getDate") != null)
    {
        dateMax = $("#txtEndDate").datepicker("getDate");
        dateMin = $("#txtEndDate").datepicker("getDate");
        dateMin.setDate(dateMin.getDate() - 7);
        if (dateMin < min)
        {
            dateMin = min;
        }           
    }
    else if (input.id == "txtEndDate")
    {
        dateMax = new Date();
        if ($("#txtStartDate").datepicker("getDate") != null)
        {
            dateMin = $("#txtStartDate").datepicker("getDate");
            dateMax = $("#txtStartDate").datepicker("getDate");
            dateMax.setDate(dateMax.getDate() + 7); 
        }
    }
    return {
     minDate: dateMin, 
     maxDate: dateMax
   }; 

}

This is the best I could come up with that met all of your requirements (I think...)

这是我能想到的最好的满足您所有要求的方法(我认为......)

回答by David Bigelow

Here is a solution I came up with after a lot of digging for a solution to what I think is a common problem. This effectively 'bounces' the inputs around a shared input range of compatible days. Meaning - if I have two fields, either one can be used to constrain the other, and the other could redefine the original if necessary. The goal of this is to always ensure that there is only a finite range of days (or months or whatever) between the the two fields. This specific example also limits the amount of time into the future that something could be selected in either field (e.g. 3 months).

这是我经过大量挖掘以解决我认为常见问题的解决方案后提出的解决方案。这有效地“反弹”了围绕兼容天数的共享输入范围的输入。含义 - 如果我有两个字段,可以使用其中一个来约束另一个,另一个可以在必要时重新定义原始字段。这样做的目标是始终确保两个字段之间只有有限的天数(或月数或其他)范围。该特定示例还限制了可以在任一字段中选择某项内容的未来时间量(例如 3 个月)。


$("#startdate").datepicker({
   minDate: '+5', 
   maxDate: '+3M',
   changeMonth: true,
   showAnim: 'blind',
   onSelect: function(dateText, inst){ 

    // Capture the Date from User Selection
    var oldDate = new Date(dateText);
    var newDate = new Date(dateText);

    // Compute the Future Limiting Date
    newDate.setDate(newDate.getDate()+5);


    // Set the Widget Properties
    $("#enddate").datepicker('option', 'minDate', oldDate);
    $("#enddate").datepicker('option', 'maxDate', newDate);

    }
  });

 $("#enddate").datepicker({
  minDate: '+5',
  maxDate: '+3M',
  changeMonth: true,
  showAnim: 'blind', 
  onSelect: function(dateText, inst){ 

    // Capture the Date from User Selection
    var endDate = new Date(dateText);
    var startDate = new Date(dateText);

    // Compute the Future Limiting Date
    startDate.setDate(startDate.getDate()-5);

    // Set the Widget Properties
    $("#startdate").datepicker('option', 'minDate', startDate);
    $("#startdate").datepicker('option', 'maxDate', endDate);

    }

  });

回答by kgiannakakis

Consider using rangeSelect to have one control instead of two.

考虑使用 rangeSelect 来拥有一个控件而不是两个控件。

To achieve what you are after, I suppose you need to add an onSelect listener and then call datepicker( "option", settings )to change the settings.

为了实现您的目标,我想您需要添加一个 onSelect 侦听器,然后调用datepicker( "option", settings )以更改设置。

回答by Ben Koehler

Your start date for txtStartDate isn't working because your second minDate is being set to null when it checks the input.id the second time. Also, maxDate should be checking for txtEndDate, not txtStartDate. Try this:

您的 txtStartDate 开始日期不起作用,因为您的第二个 minDate 在第二次检查 input.id 时被设置为 null。此外,maxDate 应该检查 txtEndDate,而不是 txtStartDate。尝试这个:

    function customRange(input) 
{ 
    var mDate = (input.id == "txtStartDate" ? new Date(2008, 12 - 1, 1) : $("#txtStartDate").datepicker("getDate"));
    return {
         minDate: mDate, 
         maxDate: (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate").getDate() + 5 : null)
       }; 
}

I don't know why the '+ 5' instead of '+ 7', but if I add 0, I get a selectable date range of the day I picked plus the next.

我不知道为什么用 '+ 5' 而不是 '+ 7',但是如果我加 0,我会得到我选择的日期加上下一天的可选日期范围。

回答by gaby

this is how i use it:

这就是我使用它的方式:

function customRange(input)
{
    var min = new Date();
    return {
        minDate: ((input.id == "txtStartDate") ? min : (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate") : null)),
        maxDate: (input.id == "txtStartDate" ? $("#txtEndDate").datepicker("getDate") : null)
    };
}

回答by escist

This is how I have done it. I have taken the source from the Jquery UI website and modified it to add your constraints.

我就是这样做的。我从 Jquery UI 网站获取了源代码并对其进行了修改以添加您的约束。

$(document).ready(function ()
{      
  var dates = $('#StartDate, #EndDate').datepicker({
        minDate: new Date(2008, 11, 1), 
        maxDate: "+0D",
        dateFormat: "dd M yy",
        changeMonth: true,
        changeYear: true,
        onSelect: function (selectedDate)
        {
            var option = this.id == "StartDate" ? "minDate" : "maxDate",
                instance = $(this).data("datepicker"),
                date = $.datepicker.parseDate(
                    instance.settings.dateFormat ||
                    $.datepicker._defaults.dateFormat,
                    selectedDate, instance.settings);
            var edate;
            var otherOption;
            var d;
            if (option == "minDate")
            {
                otherOption = "maxDate";
                d = date.getDate() + 7;
            }
            else if (option == "maxDate")
            {
                otherOption = "minDate";
                d = date.getDate() - 7;
            }

            var m = date.getMonth();
            var y = date.getFullYear();
            edate = new Date(y, m, d);

            dates.not(this).datepicker("option", option, date);
            dates.not(this).datepicker("option", otherOption, edate);
        }
    });
});

Initial Idea from: http://jqueryui.com/demos/datepicker/#date-range

最初的想法来自:http: //jqueryui.com/demos/datepicker/#date-range

Note:You would also need an option to reset/clear the dates (i.e. if a user chooses a 'From date', the 'To date' becomes limited. After choosing a 'From date' if the user now chooses a 'To date', the From date also gets limited. You need to have a clear option to allow the user to choose a different "From" date now.)

注意:您还需要一个选项来重置/清除日期(即,如果用户选择“起始日期”,则“截止日期”将受到限制。如果用户现在选择“截止日期”,则选择“起始日期”后',From 日期也受到限制。您需要有一个明确的选项,以允许用户现在选择不同的“From”日期。)