$(function () {
var $beginDate = $('#begindate');
var $beginTime = $('#begintime');
var $endDate = $('#enddate');
var $endTime = $('#endtime');
var $events = $('#events');
var $message = $('#message');
var $template = $('#event-template');
var dateRegExp = /^(\d{4})-(\d{2})-(\d{2})$/;
var timeRegExp = /^(\d{2}):(\d{2})$/;
var tempRegExp = /\{\{ *([^\}]+) *\}\}/g;
function isInvalidDate(str) {
return !(dateRegExp.test(str));
}
function isInvalidTime(str) {
return !(timeRegExp.test(str));
}
function addEvent() {
$events.append($($template.html()));
schedule();
}
function removeEvent() {
$(this).closest('div').remove();
schedule();
}
function parseMoment(dateStr, timeStr) {
var date = moment(dateStr);
var time = timeStr.match(timeRegExp).slice(1);
return date.hours(parseInt(time[0])).minutes(parseInt(time[1]));
}
function formatEvent(event) {
return $('#count-template').html().replace(tempRegExp, function (match, field) {
return event[field];
});
}
function countEvents(beginDate, endDate, events) {
events.sort(function (a, b) {
return a.date.diff(b.date);
});
do {
events.forEach(function (event) {
if (event.date.isBetween(beginDate, endDate)) {
event.count++;
}
event.date.add(1, 'd');
});
} while (events[0].date.diff(endDate) <= 0);
return events.sort(function (a, b) {
return a.order - b.order;
}).reduce(function (template, event) {
return template + formatEvent(event);
}, '');
}
function schedule() {
var beginDateStr = $beginDate.val();
var beginTimeStr = $beginTime.val();
var endDateStr = $endDate.val();
var endTimeStr = $endTime.val();
var events = $('#events input').toArray().map(function (input) {
return $(input).val();
});
if (isInvalidDate(beginDateStr)) {
$message.text('Please select a begin date');
} else if (isInvalidTime(beginTimeStr)) {
$message.text('Please select a begin time');
} else if (isInvalidDate(endDateStr)) {
$message.text('Please select an end date');
} else if (isInvalidTime(endTimeStr)) {
$message.text('Please select an end time');
} else if (events.length === 0) {
$message.text('Please add a daily event');
} else if (events.some(isInvalidTime)) {
$message.text('Please select a time for each daily event');
} else {
var beginDate = parseMoment(beginDateStr, beginTimeStr);
var endDate = parseMoment(endDateStr, endTimeStr);
events = events.map(function (timeStr, index) {
return {
order: index + 1,
count: 0,
date: parseMoment(beginDateStr, timeStr)
};
});
var message = countEvents(beginDate, endDate, events);
$message.html(message);
}
}
$('body').on('change', schedule);
$('#add').on('click', addEvent);
$('#events').on('click', '.remove', removeEvent);
schedule();
});
div {
padding: 0 0.5em 0.5em 0;
}
label[for] {
display: inline-block;
width: 60px;
text-align: right;
}
#events {
counter-reset: event;
}
label.event::before {
counter-increment: event;
content: "Event " counter(event);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
<script type="text/x-template" id="event-template">
<div>
<label class="event"></label>
<input type="time" />
<button type="button" class="remove">× Remove</button>
</div>
</script>
<script type="text/x-template" id="count-template">
<div>
Event {{order}} occurs {{count}} times
</div>
</script>
<div>
<label for="begindate">Between </label>
<input type="date" id="begindate" value="2016-07-26" />
<input type="time" id="begintime" value="11:00" />
</div>
<div>
<label for="enddate">and </label>
<input type="date" id="enddate" value="2016-07-27" />
<input type="time" id="endtime" value="14:00" />
</div>
<p id="message"></p>
<div id="events">
<h3>Daily Events</h3>
<div>
<button type="button" id="add">Add a Daily Event</button>
</div>
<div>
<label class="event"></label>
<input type="time" value="10:00" />
<button type="button" class="remove">× Remove</button>
</div>
<div>
<label class="event"></label>
<input type="time" value="12:00" />
<button type="button" class="remove">× Remove</button>
</div>
<div>
<label class="event"></label>
<input type="time" value="15:00" />
<button type="button" class="remove">× Remove</button>
</div>
</div>