Jquery Datepicker在一个日历中选择多个日期范围

时间:2017-04-18 05:24:44

标签: javascript jquery jquery-ui datepicker jquery-ui-datepicker

我的要求是允许用户在单个日历中选择多个日期范围,也不允许更改以前的日期选择。这怎么可能?以下是fiddle

的代码和链接

HTML

<p>from</p>
<input type="text" class="spromotion-input-inbody spromotion-input-datepick" id="sproid-bookingcondition-datefrom">
<p>to</p>
<input type="text" class="spromotion-input-inbody spromotion-input-datepick" id="sproid-bookingcondition-dateto">

SCRIPT

$( function() {
    var dateFormat = "mm/dd/yy",
      from = $( "#sproid-bookingcondition-datefrom" )
        .datepicker({
          defaultDate: "+1w",
          changeMonth: true,
          numberOfMonths: 1
        })
        .on( "change", function() {
          to.datepicker( "option", "minDate", getDate( this ) );
        }),
      to = $( "#sproid-bookingcondition-dateto" ).datepicker({
        defaultDate: "+1w",
        changeMonth: true,
        numberOfMonths: 1
      })
      .on( "change", function() {
        from.datepicker( "option", "maxDate", getDate( this ) );
      });

    function getDate( element ) {
      var date;
      try {
        date = $.datepicker.parseDate( dateFormat, element.value );
      } catch( error ) {
        date = null;
      }

      return date;
    }
  } );

6 个答案:

答案 0 :(得分:1)

请检查这可能会解决您的问题。

<html>
<head>
<!-- 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/3/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" />
</head>
<body>
  <input class="pull-right" type="text" name="daterange" value="01/15/2020 - 02/15/2010">
</body>
</html>
$("#j_idt87").draggable({ cancel: null });

答案 1 :(得分:0)

不幸的是,这不是datepicker插件能够开箱即用的东西。您需要一些自定义JavaScript才能启用此功能。

我发现了一种使用masteronSelect事件接近您想要的方式。它维护自己的选定日期数组,所以很遗憾没有与显示当前日期等的文本框集成。我只是将它用作内联控件,然后我可以查询数组中当前选择的日期。

您需要更改此代码的唯一方法是将每两个日期分组到范围中,但根据您所需的UX,有多种方法可以执行此操作。就个人而言,我只会按照用户选择的顺序将每两个日期分组为一个范围。然后,如果他们从任何范围中删除日期,则删除整个范围(在此处未编码,您需要添加该范围)。

这是我的代码:

beforeShowDay

这是一个小提琴:http://jsfiddle.net/gydL0epa/

答案 2 :(得分:0)

正如其他人已经建议的那样,我的MultiDatesPicker接近你的需要。它已经允许single range selection,因此您可以分叉该插件并编辑/改进它以允许多个范围选择。

快速而肮脏的解决方案是评论the line where the array of selected dates gets reset

答案 3 :(得分:0)

我认为这个多日期选择器可以帮助您解决问题。

&#13;
&#13;
$('#mdp-demo').multiDatesPicker();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.rawgit.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.css" rel="stylesheet"/>
<link href="https://code.jquery.com/ui/1.12.1/themes/pepper-grinder/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdn.rawgit.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.js"></script>
<div id="mdp-demo"></div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

好吧,伙计,伙计,我遇到了同样的问题。 这个问题是很久以前的问题了,但没关系。 您必须修改日期范围选择器。

将这两行添加到您的 daterangepicker.min.js 文件中。

var oldStartDate_list = new Array();
var oldEndDate_list = new Array();

现在我们必须为一些函数添加一些代码。只需看看“添加以下代码”行

ClickDate 函数:

 clickDate: function(t) {
        if (R(t.target).hasClass("available")) {
            var e = R(t.target).attr("data-title"),
                a = e.substr(1, 1),
                i = e.substr(3, 1),
                s = R(t.target).parents(".calendar").hasClass("left") ? this.leftCalendar.calendar[a][i] : this.rightCalendar.calendar[a][i];
            if (this.endDate || s.isBefore(this.startDate, "day")) {
                if (this.timePicker) {
                    var n = parseInt(this.container.find(".left .hourselect").val(), 10);
                    if (!this.timePicker24Hour) "PM" === (h = this.container.find(".left .ampmselect").val()) && n < 12 && (n += 12), "AM" === h && 12 === n && (n = 0);
                    var r = parseInt(this.container.find(".left .minuteselect").val(), 10),
                        o = this.timePickerSeconds ? parseInt(this.container.find(".left .secondselect").val(), 10) : 0;
                    s = s.clone().hour(n).minute(r).second(o)
                }
                this.endDate = null, this.setStartDate(s.clone())
            } else if (!this.endDate && s.isBefore(this.startDate)) this.setEndDate(this.startDate.clone());
            else {
                if (this.timePicker) {
                    var h;
                    n = parseInt(this.container.find(".right .hourselect").val(), 10);
                    if (!this.timePicker24Hour) "PM" === (h = this.container.find(".right .ampmselect").val()) && n < 12 && (n += 12), "AM" === h && 12 === n && (n = 0);
                    r = parseInt(this.container.find(".right .minuteselect").val(), 10), o = this.timePickerSeconds ? parseInt(this.container.find(".right .secondselect").val(), 10) : 0;
                    s = s.clone().hour(n).minute(r).second(o)
                }
                this.setEndDate(s.clone()), this.autoApply && (this.calculateChosenLabel(), this.clickApply())
            
                //ADD THE FOLLOWING CODE//////////
                oldStartDate_list.push(this.startDate);
                oldEndDate_list.push(this.endDate);
                //////////////////////////////////

            }
            this.singleDatePicker && (this.setEndDate(this.startDate), this.timePicker || this.clickApply()), this.updateView(), t.stopPropagation()
        }
    },

renderCalendar 函数:

  renderCalendar: function(t) {     
        var e, a = (e = "left" == t ? this.leftCalendar : this.rightCalendar).month.month(),
            i = e.month.year(),
            s = e.month.hour(),
            n = e.month.minute(),
            r = e.month.second(),
            o = H([i, a]).daysInMonth(),
            h = H([i, a, 1]),
            l = H([i, a, o]),
            c = H(h).subtract(1, "month").month(),
            d = H(h).subtract(1, "month").year(),
            m = H([d, c]).daysInMonth(),
            f = h.day();
        (e = []).firstDay = h, e.lastDay = l;
        for (var p = 0; p < 6; p++) e[p] = [];
        var u = m - f + this.locale.firstDay + 1;
        m < u && (u -= 7), f == this.locale.firstDay && (u = m - 6);
        for (var D = H([d, c, u, 12, n, r]), g = (p = 0, 0), y = 0; p < 42; p++, g++, D = H(D).add(24, "hour")) 0 < p && g % 7 == 0 && (g = 0, y++), e[y][g] = D.clone().hour(s).minute(n).second(r), D.hour(12), this.minDate && e[y][g].format("YYYY-MM-DD") == this.minDate.format("YYYY-MM-DD") && e[y][g].isBefore(this.minDate) && "left" == t && (e[y][g] = this.minDate.clone()), this.maxDate && e[y][g].format("YYYY-MM-DD") == this.maxDate.format("YYYY-MM-DD") && e[y][g].isAfter(this.maxDate) && "right" == t && (e[y][g] = this.maxDate.clone());
        "left" == t ? this.leftCalendar.calendar = e : this.rightCalendar.calendar = e;
        var k = "left" == t ? this.minDate : this.startDate,
            b = this.maxDate,
            C = ("left" == t ? this.startDate : this.endDate, this.locale.direction, '<table class="table-condensed">');
        C += "<thead>", C += "<tr>", (this.showWeekNumbers || this.showISOWeekNumbers) && (C += "<th></th>"), k && !k.isBefore(e.firstDay) || this.linkedCalendars && "left" != t ? C += "<th></th>" : C += '<th class="prev available"><span></span></th>';
        var v = this.locale.monthNames[e[1][1].month()] + e[1][1].format(" YYYY");
        if (this.showDropdowns) {
            for (var Y = e[1][1].month(), w = e[1][1].year(), P = b && b.year() || this.maxYear, x = k && k.year() || this.minYear, M = w == x, S = w == P, I = '<select class="monthselect">', B = 0; B < 12; B++)(!M || B >= k.month()) && (!S || B <= b.month()) ? I += "<option value='" + B + "'" + (B === Y ? " selected='selected'" : "") + ">" + this.locale.monthNames[B] + "</option>" : I += "<option value='" + B + "'" + (B === Y ? " selected='selected'" : "") + " disabled='disabled'>" + this.locale.monthNames[B] + "</option>";
            I += "</select>";
            for (var A = '<select class="yearselect">', L = x; L <= P; L++) A += '<option value="' + L + '"' + (L === w ? ' selected="selected"' : "") + ">" + L + "</option>";
            v = I + (A += "</select>")
        }
        if (C += '<th colspan="5" class="month">' + v + "</th>", b && !b.isAfter(e.lastDay) || this.linkedCalendars && "right" != t && !this.singleDatePicker ? C += "<th></th>" : C += '<th class="next available"><span></span></th>', C += "</tr>", C += "<tr>", (this.showWeekNumbers || this.showISOWeekNumbers) && (C += '<th class="week">' + this.locale.weekLabel + "</th>"), R.each(this.locale.daysOfWeek, function(t, e) {
                C += "<th>" + e + "</th>"
            }), C += "</tr>", C += "</thead>", C += "<tbody>", null == this.endDate && this.maxSpan) {
            var E = this.startDate.clone().add(this.maxSpan).endOf("day");
            b && !E.isBefore(b) || (b = E)
        }
        for (y = 0; y < 6; y++) {

            C += "<tr>", this.showWeekNumbers ? C += '<td class="week">' + e[y][0].week() + "</td>" : this.showISOWeekNumbers && (C += '<td class="week">' + e[y][0].isoWeek() + "</td>");
            for (g = 0; g < 7; g++) {
                var W = [];
                
                e[y][g].isSame(new Date, "day") && W.push("today"), 5 < e[y][g].isoWeekday() && W.push("weekend"), e[y][g].month() != e[1][1].month() && W.push("off"), this.minDate && e[y][g].isBefore(this.minDate, "day") && W.push("off", "disabled"), b && e[y][g].isAfter(b, "day") && W.push("off", "disabled"), this.isInvalidDate(e[y][g]) && W.push("off", "disabled"), e[y][g].format("YYYY-MM-DD") == this.startDate.format("YYYY-MM-DD") && W.push("active", "start-date"), null != this.endDate && e[y][g].format("YYYY-MM-DD") == this.endDate.format("YYYY-MM-DD") && W.push("active", "end-date"), null != this.endDate && e[y][g] > this.startDate && e[y][g] < this.endDate && W.push("in-range"); 
                
                //ADD THE FOLLOWING CODE//////////
                for (var osd_i = 0; osd_i < oldStartDate_list.length; osd_i++) {
                if(!W.includes("start-date") && !W.includes("end-date") && 
                e[y][g].format("YYYY-MM-DD") == oldStartDate_list[osd_i].format("YYYY-MM-DD")) {
                W.push("active", "start-date")  
                if(W.includes("in-range"))
                W.splice(W.indexOf("in-range"),1);}
                if(!W.includes("start-date") && !W.includes("end-date") && 
                e[y][g].format("YYYY-MM-DD") == oldEndDate_list[osd_i].format("YYYY-MM-DD")) {
                W.push("active", "end-date")    
                if(W.includes("in-range"))
                W.splice(W.indexOf("in-range"),1);}
                if(!W.includes("start-date") && !W.includes("end-date") && !W.includes("in-range") && 
                e[y][g] > oldStartDate_list[osd_i] && e[y][g] < oldEndDate_list[osd_i])
                W.push("in-range");} 
                //////////////////////////////////
                
                var O = this.isCustomDate(e[y][g]);
                !1 !== O && ("string" == typeof O ? W.push(O) : Array.prototype.push.apply(W, O));
                var N = "",
                    j = !1;
                for (p = 0; p < W.length; p++) N += W[p] + " ", "disabled" == W[p] && (j = !0);
                j || (N += "available"), C += '<td class="' + N.replace(/^\s+|\s+$/g, "") + '" data-title="r' + y + "c" + g + '">' + e[y][g].date() + "</td>"
            }
            C += "</tr>"
        }
        C += "</tbody>", C += "</table>", this.container.find(".calendar." + t + " .calendar-table").html(C) 
        
    },

clickCancel 函数:

 clickCancel: function(t) {             
            //ADD THE FOLLOWING CODE//////////                  
            oldStartDate_list.length = 0;
            oldEndDate_list.length = 0;
            //////////////////////////////////
        this.startDate = this.oldStartDate, this.endDate = this.oldEndDate; this.hide(), this.element.trigger("cancel.daterangepicker", this)
    },

现在您应该可以选择多个范围:look here

玩得开心

嗯,是的,我使用了 min js 并首先通过美化器追逐它。你当然也可以使用普通的 daterangepicker.js,它很好,显然更具可读性......无论如何......哈哈哈哈哈

只是一种方法^^!!卡沃

答案 5 :(得分:-1)

试试这个

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="Scripts/jquery-1.11.1.js"></script>
    <script src="Scripts/jquery-ui-1.11.1.js"></script>
    <script src="Scripts/jquery-ui.multidatespicker.js"></script>
    <link href="css/jquery-ui.css" rel="stylesheet" />
    <link href="css/jquery-ui.structure.css" rel="stylesheet" />
    <link href="css/jquery-ui.theme.css" rel="stylesheet" />
    <link href="css/pepper-ginder-custom.css" rel="stylesheet" />
    <link href="css/prettify.css" rel="stylesheet" />
</head>

<body>
    <input type="text" id="fromDate" />
    <script>
        $(function () {
            $('#fromDate').multiDatesPicker();
        });
    </script>
</body>
</html>

您可以从链接https://sourceforge.net/projects/multidatespickr/

下载js文件