使用 Javascript 从日历中选择多个日期

Selecting multiple dates from a calendar with Javascript

我有一个日历,它是使用 PHP/MySQL 数据库源的 HTML 结构。日历一次输出为一个月,其中包含预订日期、过去日期和未来日期以及当前日期的列表。我的目标是让客户使用日历 select 他们假期的开始和结束日期。

我目前使用 PHP 5.5 和 HTML5,CSS 3 和 JQuery 1.11.0。 我当前的代码在 https://jsfiddle.net/rs7mcoo9/4/

的 JSFiddle 中

日历当前的功能:

我的日历当前在一个月中的每一天都有一个 DIV 标签,其中包含两个自定义日期 - 作为时间戳的日期值和作为人工文本的日期值。单击可用日期时,日期显示为绿色,日期文本显示 - 通过 JQuery - 在预订表单字段中。

我希望日历执行的操作:

我正在寻找的是点击日历的第一个日期并且日期显示在预订表格中的东西,但是当第二个日期在日历上点击时 两者之间的每个日期 显示一个 CSS 绿日规则,向用户提供一个清晰简洁的定义,他们有什么日期 selected,例如,如果第一个是单击然后单击第 4 个,然后第 1、2、3 和 4 个日历 div 被着色以显示这些将是 selected 的。

我设想可以通过使用 JQuery 更改日历上各种 selected 日期的 CSS 设置来解决这个问题,但我的问题是我不能找到一种巧妙的方法来select设置正确的日期,一旦设置了第一个开始日期,鼠标悬停在以后的日期上就需要更改这些日期。

我是如何尝试解决我的问题的

我查看了 http://multidatespickr.sourceforge.net/ and http://stefangabos.ro/jquery/zebra-datepicker/ 日期选择 UI,但这些并不能满足我的要求,它们让用户必须单击他们需要的每一天,而不是 select 查看所有日期在开始日期和结束日期之间。

我还查看了其他一些 SO 问题,例如 p:calender multiple date selection,但这些问题并没有帮助我掌握如何启动此功能。

工作示例

我有一个当前设置的工作示例:https://jsfiddle.net/rs7mcoo9/4/。请注意,在此设置中,日期清除按钮 "clear" 不起作用。

每个可供预订的日期都在其 DIV 中设置了两个自定义值:

    <td class="provbook" title='Sunday, September 13, 2015 (available - click to book)'>
<div data-value='13th September 2015' data-core='20150913'>13</div>
</td>

date-core 值设置为 YMD,因此应该很容易计算出日期 after/before 的数字。我目前的 JQuery 是:

$(document).ready(function() {
        $("#mailbox").css("display","block");

        $('td > div').on('click', function() {
            $('#mailbox').show(360);
            $(this).toggleClass( "dateChoice" )
            var dateValueOutput = $(this).attr('data-value');
            var dataCore =  parseInt($(this).attr('data-core'));
            var checkDataA = parseInt($('#coreDateA').val());
            if (isNaN(checkDataA)) {
                checkDataA = 0;
                $('#coreDateA').val();
            }
            var checkDataB = parseInt($('#coreDateB').val());
            if (isNaN(checkDataB)) {
                checkDataB = 0;
                $('#coreDateB').val();
            }
            if (dataCore < checkDataA || checkDataA == 0 ) {

                $('#bookDatesa').val(dateValueOutput);
                $('#coreDateA').val(dataCore);
            }
            else {
                $('#bookDates').val(dateValueOutput);
                $('#coreDateB').val(dataCore);
            }
            /** If input box is empty then also clear hidden field **/
            /** change CSS of selected boxes, for start/finish **/
            /** so If css colour is set, change to clear etx. **/
        });
    });

后续步骤

我想使用 JQuery 来实现我想要的交互性,我需要一些帮助来开始如何让我的 JQuery/javascript 解决这个问题。我如何才能实现我的目标,我对 JQuery 的了解有些敷衍,特别是我正在寻找要使用的语法,以便任何 DIV date-core 值等于或高于主要值日期 (var checkDataA) 和小于第二个日期 selected,并且对于这些选定的单元格 / DIVS 应用自定义 CSS class.

非常感谢您的帮助!!

更新

基本上我想要一种方法将 CSS 规则应用到所有 DIV 标签,这些标签介于到(日期)值之间,这些值记录在 data-core 中DIV 元素。 因此,如果有人在一个月的第 13 天 (20151013) 和一个月的第 18 天 (20151018) 单击,那么在这两个日期之间包含 data-core 值的 DIV 都会获得额外的 CSS 规则通过 Javascript 应用于他们。

非常感谢

这是 select 间隔 selected:

的代码
var firstDate = $('#coreDateA').val();
var lastDate = $('#coreDateB').val();

if (firstDate && lastDate) {
  //date format is 20150918
  var firstDay = parseInt(firstDate.substring(6));
  var yearAndMonth = firstDate.substring(0,6);
  var lastDay = parseInt(lastDate.substring(6));

  //reset all selections
  $('td > div').removeClass('dateChoice'); 

  for (var i = firstDay; i <= lastDay; i++){
     $('div[data-core="' + yearAndMonth + i +'"]').addClass('dateChoice');
  }
}

这是 fiddle,您可以在其中看到工作: https://jsfiddle.net/ozsq6wex/3/

不过请注意,如果您想 select 跨月,例如从 9 月开始到 10 月结束,您将需要更复杂的逻辑才能实现

更改 coreDateAcoreDateB 的值后,您可以在使用 each 函数和一个条件语句之间更改所有元素 class .只需在 click 函数

的末尾添加此代码
var i=$("#coreDateA").val();
var j=$("#coreDateB").val()||i;
$("[data-core]").each(function(){
    var timestamp=parseInt($(this).attr("data-core"));
    var flagClass=$(this).hasClass("dateChoice");
    if(timestamp>=i&&timestamp<=j){
        if(!flagClass)
            $(this).addClass("dateChoice");
    }
    else if(flagClass)
         $(this).removeClass("dateChoice");
});    

演示

$(document).ready(function() {
        $("#mailbox").css("display","block");

        $('td > div').on('click', function() {
            $('#mailbox').show(360);
            $(this).toggleClass( "dateChoice" )
            var dateValueOutput = $(this).attr('data-value');
            var dataCore =  parseInt($(this).attr('data-core'));
            var checkDataA = parseInt($('#coreDateA').val());
            if (isNaN(checkDataA)) {
                checkDataA = 0;
            }
            var checkDataB = parseInt($('#coreDateB').val());
            if (isNaN(checkDataB)) {
                checkDataB = 0;
            }
            if (dataCore < checkDataA || checkDataA == 0 ) {

                $('#bookDatesa').val(dateValueOutput);
                $('#coreDateA').val(dataCore);
            }
            else {
                $('#bookDates').val(dateValueOutput);
                $('#coreDateB').val(dataCore);
            }
            var i=$("#coreDateA").val();
            var j=$("#coreDateB").val()||i;
            $("[data-core]").each(function(){
             var timestamp=parseInt($(this).attr("data-core"));
                var flagClass=$(this).hasClass("dateChoice");
                if(timestamp>=i&&timestamp<=j){
                    if(!flagClass)
                        $(this).addClass("dateChoice");
                }
             else if(flagClass)
                    $(this).removeClass("dateChoice");
             });    
   
   
        });
    });
.provbook {
 font-weight: bold !important;
 color:#009 !important;
}
.provbook:hover {
 cursor: pointer;
 background-color:#11cc33;
}
.dateChoice, .dateChoice:hover, .dateChoice:focus {
 background-color:#11dd11 !important;
 color:#006 !important;
}
.tariffTable {
 min-width:320px;
 width:80%;
 margin: 0 auto 1em auto;
 border: 1px solid #AAA;
 background-color: #FFF;
 font-size: 0.9em;
 line-height: 1.3em;
 border-collapse: collapse;
}
.calendar {
 padding: 0;
 font-family: Arial, Helvetica, sans-serif;
 font-size: 0.9em;
 min-width: 320px;
 width:80%;
 max-width:600px;
 margin: 0 auto;
 border: 1px solid #AAA;

}
.calendar caption {
 margin: 0;
 padding: .3em 0;
 border-top:#006 1px none;
 border-right:#AAA 1px solid;
 border-left: #AAA 1px solid;
 font-weight: bold;
 background-color: #FFF;
 color: #000;
 font-size: 1.05em;
}
.calendar th {
 border-bottom: 1px solid #ccc;
 font-weight: normal;
 background: #fff;
 text-align: center;
}
.calendar td {
 border: 1px solid #fff;
 padding: .1em .3em ;
 width: 1em;
 text-align: center;
}
/*.calendar a {
 color: #000;
 text-decoration: none;
}*/

.calendar td.today {
 background: #CCC !important;
 font-weight: normal;
 color:#333;
 }
/*
.calendar td.selected {
 border: 1px dotted #ff7800;
 }
 */
.calendar td.highlighted {
 background-color: #C6B6AE;
 font-weight: normal;
 color:#000;
}
.calendar td.passed {
 font-style: italic;
 font-weight: normal;
 color:#333;
}
.highlightedExample {
 background-color: #C6B6AE;
 padding:0.15em 0.5em;
}
/*
.calendar td:hover, .calendar td.today:hover,
.calendar td.selected:hover, .calendar td.highlighted:hover {
 border: 1px solid #009999;
 }
 */

table.calendar td.pad {
 color: #999;
 background: #fff;
}
table.calendar td.pad:hover {
 background: none;
 border: 0;
}

.tariffTable tr td {
 padding:0.2em;
}
.tariffTable th {
 font-size: 1em;
 font-weight: bold;
 color: #000;
 border-bottom:#AAA 1px solid;
 padding:0.4em 0.3em;
 text-align: left;
}
.tariffTable th:nth-child(n+3), .tariffTable tr td:nth-child(n+3) {
 text-align: center !important;
}
.tariffTable tr td {

}
.tariffTable tr:nth-child(even) {
 background-color: #DDD;
}
.tariffTable tr:nth-child(odd) {
 background-color: #EEE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table class='calendar'>
<caption>September 2015</caption>
<col class='sunday' />
<col class='monday' />
<col class='tuesday' />
<col class='wednesday' />
<col class='thursday' />
<col class='friday' />
<col class='saturday' />
<thead>
<tr>
 <th title='Sunday'>S</th>
 <th title='Monday'>M</th>
 <th title='Tuesday'>T</th>
 <th title='Wednesday'>W</th>
 <th title='Thursday'>T</th>
 <th title='Friday'>F</th>
 <th title='Saturday'>S</th>
</tr>
</thead>
<tbody>
<tr>
 <td class='pad'>&nbsp;</td>
 <td class='pad'>&nbsp;</td>
 <td class="highlighted" title='Tuesday, September  1, 2015 (booked)'><div data-value='1st September 2015' data-core='20150901'>01</div></td>
 <td class="highlighted" title='Wednesday, September  2, 2015 (booked)'><div data-value='2nd September 2015' data-core='20150902'>02</div></td>
 <td class="highlighted" title='Thursday, September  3, 2015 (booked)'><div data-value='3rd September 2015' data-core='20150903'>03</div></td>
 <td class="highlighted" title='Friday, September  4, 2015 (booked)'><div data-value='4th September 2015' data-core='20150904'>04</div></td>
 <td class="highlighted" title='Saturday, September  5, 2015 (booked)'><div data-value='5th September 2015' data-core='20150905'>05</div></td>
</tr>
<tr>
 <td class="highlighted" title='Sunday, September  6, 2015 (booked)'><div data-value='6th September 2015' data-core='20150906'>06</div></td>
 <td class="highlighted" title='Monday, September  7, 2015 (booked)'><div data-value='7th September 2015' data-core='20150907'>07</div></td>
 <td class="highlighted" title='Tuesday, September  8, 2015 (booked)'><div data-value='8th September 2015' data-core='20150908'>08</div></td>
 <td class="highlighted" title='Wednesday, September  9, 2015 (booked)'><div data-value='9th September 2015' data-core='20150909'>09</div></td>
 <td class="highlighted" title='Thursday, September 10, 2015 (booked)'><div data-value='10th September 2015' data-core='20150910'>10</div></td>
 <td class="highlighted" title='Friday, September 11, 2015 (booked)'><div data-value='11th September 2015' data-core='20150911'>11</div></td>
 <td class="provbook" title='Saturday, September 12, 2015 (available - click to book)'><div data-value='12th September 2015' data-core='20150912'>12</div></td>
</tr>
<tr>
 <td class="provbook" title='Sunday, September 13, 2015 (available - click to book)'><div data-value='13th September 2015' data-core='20150913'>13</div></td>
 <td class="provbook" title='Monday, September 14, 2015 (available - click to book)'><div data-value='14th September 2015' data-core='20150914'>14</div></td>
 <td class="provbook" title='Tuesday, September 15, 2015 (available - click to book)'><div data-value='15th September 2015' data-core='20150915'>15</div></td>
 <td class="provbook" title='Wednesday, September 16, 2015 (available - click to book)'><div data-value='16th September 2015' data-core='20150916'>16</div></td>
 <td class="provbook" title='Thursday, September 17, 2015 (available - click to book)'><div data-value='17th September 2015' data-core='20150917'>17</div></td>
 <td class="provbook" title='Friday, September 18, 2015 (available - click to book)'><div data-value='18th September 2015' data-core='20150918'>18</div></td>
 <td class="provbook" title='Saturday, September 19, 2015 (available - click to book)'><div data-value='19th September 2015' data-core='20150919'>19</div></td>
</tr>
<tr>
 <td class="provbook" title='Sunday, September 20, 2015 (available - click to book)'><div data-value='20th September 2015' data-core='20150920'>20</div></td>
 <td class="provbook" title='Monday, September 21, 2015 (available - click to book)'><div data-value='21st September 2015' data-core='20150921'>21</div></td>
 <td class="provbook" title='Tuesday, September 22, 2015 (available - click to book)'><div data-value='22nd September 2015' data-core='20150922'>22</div></td>
 <td class="provbook" title='Wednesday, September 23, 2015 (available - click to book)'><div data-value='23rd September 2015' data-core='20150923'>23</div></td>
 <td class="provbook" title='Thursday, September 24, 2015 (available - click to book)'><div data-value='24th September 2015' data-core='20150924'>24</div></td>
 <td class="provbook" title='Friday, September 25, 2015 (available - click to book)'><div data-value='25th September 2015' data-core='20150925'>25</div></td>
 <td class="provbook" title='Saturday, September 26, 2015 (available - click to book)'><div data-value='26th September 2015' data-core='20150926'>26</div></td>
</tr>
<tr>
 <td class="provbook" title='Sunday, September 27, 2015 (available - click to book)'><div data-value='27th September 2015' data-core='20150927'>27</div></td>
 <td class="provbook" title='Monday, September 28, 2015 (available - click to book)'><div data-value='28th September 2015' data-core='20150928'>28</div></td>
 <td class="provbook" title='Tuesday, September 29, 2015 (available - click to book)'><div data-value='29th September 2015' data-core='20150929'>29</div></td>
 <td class="provbook" title='Wednesday, September 30, 2015 (available - click to book)'><div data-value='30th September 2015' data-core='20150930'>30</div></td>
 <td class='pad'>&nbsp;</td>
 <td class='pad'>&nbsp;</td>
 <td class='pad'>&nbsp;</td>
</tr>
</tbody>
</table>

 <div id='mailbox'>
             <form action='' method='post' enctype='multipart/form-data'
             lang='en' name='enqform'>
                 <br>From (<span id='clearFrom'>clear</span>):
            <input type='text' value='' name='datesa' id='bookDatesa' required>
            <input type='hidden' value='' name='coreDateA' id='coreDateA'>
            <input type='hidden' value='' name='coreDateB' id='coreDateB'>
 To (<span id='clearTo'>clear</span>):<br>
            <input type='text' value='' name='dates' id='bookDates' required>

             <input type='submit' value='Send Enquiry' name='submit'>
             </form>
             </div>