Using eonasdan/bootstrapdatetimepicker, I try to solve this:
How to set disabledTimeIntervals, minDate and maxDate for each dynamically created time-input-field? minDate and maxDate has to be set to the corresponding field, while disabledTimeIntervals has to be set to all fields, except the edited fields - also on every edit.
I do not have any glue to get this done.
Has anyone a solution for this?
$(document).ready(function() {
$("#timeday0from").datetimepicker({
format: "LT",
allowInputToggle: true,
ignoreReadonly: true
});
$("#timeday0until").datetimepicker({
format: "LT",
allowInputToggle: true,
ignoreReadonly: true
});
$("#timeday0from").on("dp.change", function(e) {
$("#timeday0until")
.data("DateTimePicker")
.minDate(e.date);
});
$("#timeday0until").on("dp.change", function(e) {
$("#timeday0from")
.data("DateTimePicker")
.maxDate(e.date);
});
});
var i = 0;
var day = "day_";
var original = document.getElementById(day + i);
function duplicateElement() {
var clone = original.cloneNode(true);
i++;
clone.id = day + i; // there can only be one element with an ID
clone.childNodes;
for (var input of $(".timeday0from", clone)) {
input.id = "time" + clone.id + "from";
}
for (var input of $(".timeday0until", clone)) {
input.id = "time" + clone.id + "until";
}
for (var select of $(".timeday0type", clone)) {
select.id = "time" + clone.id + "info";
}
for (var input of $(".timeday0from", clone)) {
input.name = "time[" + day + "][" + i + "][from]";
}
for (var input of $(".timeday0until", clone)) {
input.name = "time[" + day + "][" + i + "][until]";
}
for (var select of $(".timeday0type", clone)) {
select.name = "time[" + day + "][" + i + "][type]";
}
for (var input of $(".timeday0from", clone)) {
input.value = "";
}
for (var input of $(".timeday0until", clone)) {
input.value = "";
}
for (var select of $(".timeday0type", clone)) {
select.value = "";
}
original.parentNode.appendChild(clone);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/css/bootstrap-datetimepicker.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-lg-6 col-md-12">
<div class="well">
<h3>Day</h3>
<div class="row" id="day_0">
<div class="form-group col-sm-4 col-xs-6">
<label for="timeday0from" class="control-label">Interval starts</label>
<div class='input-group date' id='timeday0from'>
<input type="text" class="form-control datepicker timeday0from" name="time[day][0][from]" readonly="readonly"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
<div class="form-group col-sm-4 col-xs-6">
<label for="timeday0until" class="control-label">Interval ends</label>
<div class='input-group date' id='timeday0until'>
<input type="text" class="form-control datepicker timeday0until" name="time[day][0][until]" readonly="readonly"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
<div class="form-group col-sm-4 col-xs-12">
<label for="timeday0info" class="control-label">Interval-Option</label>
<select name="time[day][0][info]" class="form-control timeday0type" id="timeday0info">
<option>Bitte auswählen</option>
</select>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-default" onclick="duplicateElement();"><span class="glyphicon glyphicon-plus"></span></button>
Creating works. But I do not have any idea, how to set maxDate, minDate and disabledTimeIntervals (overlapping of ranges should prevented) on clone/remove of elemen and update of a time-field.
What a mess - but it works!
$.fn.datetimepicker.defaults.tooltips = {
today: 'Heute',
clear: 'Auswahl leeren',
incrementMinute: 'später',
decrementMinute: 'früher',
incrementHour: 'später',
decrementHour: 'früher',
pickHour: 'Stunde wählen',
pickMinute: 'Minute wählen'
};
$.fn.datetimepicker.defaults.useCurrent = false;
$.fn.datetimepicker.defaults.ignoreReadonly = true;
$.fn.datetimepicker.defaults.allowInputToggle = true;
$.fn.datetimepicker.defaults.locale = 'de';
$.fn.datetimepicker.defaults.showClear = true;
$(document).ready(function() {
initDateTimePair('day',0);
updateMin('day',0);
updateMax('day',0);
});
var i = 0;
var original = document.getElementById('day' +'_'+ i);
function initDateTimePair(day, item){
$("#time"+day+item+"from").datetimepicker({
format: "LT",
allowInputToggle: true,
ignoreReadonly: true
});
$("#time"+day+item+"until").datetimepicker({
format: "LT",
allowInputToggle: true,
ignoreReadonly: true
});
}
function updateMax(day, item){
$("#time"+day+item+"from").on("dp.change", function(e) {
$("#time"+day+item+"until").data("DateTimePicker").minDate(e.date);
if($('#time'+day+item+'until').data("DateTimePicker")){
updateDisabledTimes(day, item);
}
});
}
function updateMin(day, item){
$("#time"+day+item+"until").on("dp.change", function(e) {
$("#time"+day+item+"from").data("DateTimePicker").maxDate(e.date);
if($('#time'+day+item+'from').data("DateTimePicker")){
updateDisabledTimes(day, item);
}
});
}
function initDisabledTimes(day, item){
var arr = collectDisabledTime(day, null);
$('#time'+day+item+'from').data("DateTimePicker").disabledTimeIntervals(arr);
$('#time'+day+item+'until').data("DateTimePicker").disabledTimeIntervals(arr);
}
function updateDisabledTimes(day, item){
for(l=0; l<=i; l++) {
var arr = collectDisabledTime(day, item);
if(l!=item){
$('#time'+day+l+'from').data("DateTimePicker").disabledTimeIntervals(arr);
$('#time'+day+l+'until').data("DateTimePicker").disabledTimeIntervals(arr);
}
}
}
function collectDisabledTime(day, item){
var arr = [];
for(j=0; j<=i; j++){
if(j!=item){
var from = $('#time'+day+j+'from').data("DateTimePicker");
var until = $('#time'+day+j+'until').data("DateTimePicker");
if(until !== undefined && until.date() !== null && from !== undefined && from.date() !== null){
arr.push([$('#time'+day+j+'from').data("DateTimePicker").date().add(1,'minute'), $('#time'+day+j+'until').data("DateTimePicker").date().add(-1,'minute')]);
}
}
}
return arr;
}
function duplicateElement(day) {
var clone = original.cloneNode(true);
i++;
clone.id = day + '_' + i; // there can only be one element with an ID
clone.childNodes;
for (var input of $(".time"+day+"from", clone)) {
input.id = "time" + day + i + "from";
}
for (var input of $(".time"+day+"until", clone)) {
input.id = "time" + day + i + "until";
}
for (var select of $(".time"+day+"type", clone)) {
select.id = "time" + day + i + "info";
}
for (var input of $(".time"+day+"from", clone)) {
input.name = "time[" + day + "][" + i + "][from]";
}
for (var input of $(".time"+day+"until", clone)) {
input.name = "time[" + day + "][" + i + "][until]";
}
for (var select of $(".time"+day+"type", clone)) {
select.name = "time[" + day + "][" + i + "][type]";
}
for (var input of $(".time"+day+"from", clone)) {
input.value = "";
}
for (var input of $(".time"+day+"until", clone)) {
input.value = "";
}
for (var select of $(".time"+day+"type", clone)) {
select.value = "-1";
}
original.parentNode.appendChild(clone);
initDateTimePair(day, i);
updateMin(day, i);
updateMax(day, i);
initDisabledTimes(day, i);
updateDisabledTimes(day, i);
console.log($('#timeday'+i+'from').data("DateTimePicker").disabledTimeIntervals())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/locale/de.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/css/bootstrap-datetimepicker.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div class="col-lg-6 col-md-12">
<div class="well">
<h3>Day</h3>
<div class="row" id="day_0">
<div class="form-group col-sm-4 col-xs-6">
<label for="timeday0from" class="control-label">Interval starts</label>
<div class='input-group date' id='timeday0from'>
<input type="text" class="form-control datepicker timedayfrom" name="time[day][0][from]" readonly="readonly"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
<div class="form-group col-sm-4 col-xs-6">
<label for="timeday0until" class="control-label">Interval ends</label>
<div class='input-group date' id='timeday0until'>
<input type="text" class="form-control datepicker timedayuntil" name="time[day][0][until]" readonly="readonly"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
<div class="form-group col-sm-4 col-xs-12">
<label for="timeday0info" class="control-label">Interval-Option</label>
<select name="time[day][0][info]" class="form-control timedaytype" id="timeday0info">
<option value="-1">Bitte auswählen</option>
</select>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-default" onclick="duplicateElement('day');"><span class="glyphicon glyphicon-plus"></span></button>