繁体   English   中英

使用事件克隆Eonasdan DateTimePicker

[英]Cloning Eonasdan DateTimePicker with Events

我正在创建一个具有两个选择器的表单,以计算日期之间的差异。

用户可以创建更多的日期间隔,并且应该计算特定的间隔。

我遇到的问题是:无论我做什么都克隆了选择器之后,所有其他克隆的选择器都会激活第一个选择器。

计算在页面加载和选择器的hide事件之后发生。

我知道我必须在创建时初始化新的选择器,并且可以这样做,但是我不确定它是否有效。

我该如何进行这项工作? 我知道,如果我从clone()删除true ,则选择器可以工作,但是克隆无法激活用于计算的事件。

 var tomorrow = moment().add(1, 'day'); var startOfYearMoment = moment(tomorrow) var endOfYearMoment = moment(tomorrow.add(1, 'year')); function destroyPickers(nrOfSiblings) { // console.log("DELETED"); for (let i = 0; i < nrOfSiblings; i++) { // console.log(i); $("#inicio" + i).data("DateTimePicker").destroy(); $("#fim" + i).data("DateTimePicker").destroy(); } } function updatePickers(nrOfSiblings) { // console.log("UPDATED"); for (let i = 0; i < nrOfSiblings + 1; i++) { // console.log(i); initDatePickers("inicio" + i, "fim" + i); } } function initDatePickers(idInicio, idFim) { //, parentInicio, parentFim) { $("#" + idInicio).datetimepicker({ locale: 'pt', ignoreReadonly: true, focusOnShow: false, viewMode: 'months', format: 'DD/MM/YYYY', defaultDate: startOfYearMoment, // widgetParent: $(parentInicio), widgetPositioning: { horizontal: 'auto', vertical: 'auto' }, icons: { time: 'calendarIcon time', date: 'calendarIcon date', up: 'calendarIcon up', down: 'calendarIcon down', previous: 'calendarIcon prev', next: 'calendarIcon next', today: 'calendarIcon today', clear: 'calendarIcon clear', close: 'calendarIcon close' } }); $("#" + idFim).datetimepicker({ locale: 'pt', ignoreReadonly: true, focusOnShow: false, viewMode: 'months', format: 'DD/MM/YYYY', defaultDate: endOfYearMoment, // widgetParent: $(parentFim), widgetPositioning: { horizontal: 'auto', vertical: 'auto' }, icons: { time: 'calendarIcon time', date: 'calendarIcon date', up: 'calendarIcon up', down: 'calendarIcon down', previous: 'calendarIcon prev', next: 'calendarIcon next', today: 'calendarIcon today', clear: 'calendarIcon clear', close: 'calendarIcon close' } }); } function getDisponibilidade(startDate, endDate, targetDiv) { if (endDate.isSameOrBefore(startDate, 'day month year')) { $("#" + targetDiv + " .fim").popover('show'); } else $("#" + targetDiv + " .fim").popover('hide'); //console.log(moment.duration(endDate.diff(startDate)).as('days')); var duration = Math.round(moment.duration(endDate.diff(startDate)).as('days')); if (duration <= 0) { $("#" + targetDiv + " .dias").replaceWith('<span class="dias">0 days</span>'); } else if (duration > 1) { $("#" + targetDiv + " .dias").replaceWith('<span class="dias">' + duration + ' days</span>'); } else $("#" + targetDiv + " .dias").replaceWith('<span class="dias">' + duration + ' day</span>'); //console.log(duration); return duration } $(document).ready(function() { initDatePickers("inicio0", "fim0"); var startDate = $("#inicio0").data("DateTimePicker").date(); var endDate = $("#fim0").data("DateTimePicker").date(); getDisponibilidade(startDate, endDate, "dispRow0") }); $("input.dispDtp").on("dp.hide", function(event) { if (event.target.id.match(/inicio\\d/)) { var startDateInpt = event.target.id; var endDateInpt = $(this).parent().siblings().children("input[id^='fim']")[0].id; /* console.log(event); console.log($(this)); */ } else { var startDateInpt = $(this).parent().siblings().children("input[id^='inicio']")[0].id; var endDateInpt = event.target.id; } var targetDiv = $(this).parents("div[id^='dispRow']")[0].attributes[1].value; /* console.log(startDateInpt); console.log(endDateInpt); */ var startDate = $("#" + targetDiv + " #" + startDateInpt).data("DateTimePicker").date(); var endDate = $("#" + targetDiv + " #" + endDateInpt).data("DateTimePicker").date(); getDisponibilidade(startDate, endDate, targetDiv); }); $(".addDisp button").click(function(event) { $("#dispRow0").clone(true,true).appendTo(".disp").prop("id", "newDisp"); var sibLength = $("#dispRow0").siblings().length; $("#newDisp div[id^='dispDtpDivInicio']").attr("class", "dispDtpDivInicio" + sibLength); $("#newDisp input[id^='inicio']").attr("name", "dataInicio" + sibLength).prop("id", "inicio" + sibLength); $("#newDisp div[id^='dispDtpDivFim']").attr("class", "dispDtpDivFim" + sibLength); $("#newDisp input[id^='fim']").attr("name", "dataInicio" + sibLength).prop("id", "fim" + sibLength); $("#newDisp .remDisp button").prop("id", "remDispBtn" + sibLength); destroyPickers(sibLength); updatePickers(sibLength); $("#newDisp").attr("id", "dispRow" + sibLength); // console.log($("#dispRow0").siblings()); }) 
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.css" /> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script> <div class="row"> <div class="col-12 disp"> <div class="form-row" id="dispRow0"> <div class="formGroup col-2 dispDtpDivInicio0"> <label for="dataInicio0" class=" ">start</label> <input name="dataInicio0" type="text" class="form-control dispDtp" id="inicio0" readonly required style="position:relative;"> </div> <div class="formGroup col-2 dispDtpDivFim0"> <label for=" dataFim0" class=" ">end</label> <input name="dataFim0" type="text " class="form-control dispDtp" id="fim0" readonly required style="position:relative;"> <small class="form-text text-muted "> <span class="dias ">0 days</span> </small> </div> </div> </div> </div> <div class="row "> <div class="col-12 addDisp"> <button type="button"> <h5> Add </h5> </button> </div> </div> 

我搜索了一下,发现了几个问题,但是没有一个能像我需要的那样工作

问题1

问题2

编辑: JSFiddle如果需要的话:

将其作为组织,重用代码和关注点分离方面的课程。

无论何时使用模块化组件,都希望将它们隔离开,以使它们彼此之间不依赖。 因此,首先,我建议不要克隆初始化的对象,也不要克隆带有事件的东西。

因此,我创建了一个“视图”模板。 如您所知,需要特别注意的一点是,您必须匹配forname属性...我只是为此使用uuid,这将确保两个uuid永远不会相同。 索引工作可以很好地完成,但是随后您必须跟踪该索引。 由你决定。

每次有人单击添加时都会初始化视图模板,并且在文档加载时首先调用一次。

初始化为模板做准备,调用日期选择器初始化,并添加事件处理程序。

希望这可以帮助。

 var tomorrow = moment().add(1, 'day'); var startOfYearMoment = moment(tomorrow) var endOfYearMoment = moment(tomorrow.add(1, 'year')); function calculateDays($inicio,$fim){ return function(event) { var startDate = $inicio.data("DateTimePicker").date(); var endDate = $fim.data("DateTimePicker").date(); var $span = $fim.parent().find('.dias'); getDisponibilidade(startDate, endDate, $span); }; } function initDatePickers($inicio,$fim) { //, parentInicio, parentFim) { var options = { locale: 'pt', ignoreReadonly: true, focusOnShow: false, viewMode: 'months', format: 'DD/MM/YYYY', // widgetParent: $(parentInicio), widgetPositioning: { horizontal: 'auto', vertical: 'auto' }, icons: { time: 'calendarIcon time', date: 'calendarIcon date', up: 'calendarIcon up', down: 'calendarIcon down', previous: 'calendarIcon prev', next: 'calendarIcon next', today: 'calendarIcon today', clear: 'calendarIcon clear', close: 'calendarIcon close' } }; options.defaultDate = startOfYearMoment, $inicio.datetimepicker(options); options.defaultDate = endOfYearMoment; $fim.datetimepicker(options); var hideHandler = calculateDays($inicio,$fim); $inicio.on("dp.hide",hideHandler); $fim.on("dp.hide",hideHandler); hideHandler(); // run once. } function getDisponibilidade(startDate, endDate, $span) { var duration = Math.round(moment.duration(endDate.diff(startDate)).as('days')); if (duration <= 0) { $span.text("0"); }else{ $span.text(duration); } return duration } $(document).ready(function() { addDateDurationWidget(); // Add an initial date widgit. }); function addDateDurationWidget(){ var $template = $("#view-templates .view").clone() var uu1 = uuid(); var uu2 = uuid(); var replaceUuid = function(uu){ return function(i,s){return s.replace(/{{uuid}}/,uu)} } $template.find('.dispDtpDivInicio label').attr("for",replaceUuid(uu1)) $template.find('.dispDtpDivInicio input').attr("name",replaceUuid(uu1)) $template.find('.dispDtpDivFim label').attr("for",replaceUuid(uu2)) $template.find('.dispDtpDivFim input').attr("name",replaceUuid(uu2)) $template.appendTo(".disp").prop("id", "newDisp"); $inicio = $template.find('input.inicio'); $fim = $template.find('input.fim'); initDatePickers($inicio,$fim); } $(".addDisp button").click(function(event) { addDateDurationWidget(); }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/node-uuid/1.4.8/uuid.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.css" /> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script> <div class="row"> <div class="col-12 disp"> </div> </div> <div class="row "> <div class="col-12 addDisp"> <button type="button"> <h5> Add </h5> </button> </div> </div> <div id="view-templates" style="display:none;"> <div class="form-row view"> <div class="formGroup col-2 dispDtpDivInicio"> <label for="dataInicio-{{uuid}}" class=" ">start</label> <input name="dataInicio-{{uuid}}" type="text" class="form-control inicio dispDtp" readonly required style="position:relative;"> </div> <div class="formGroup col-2 dispDtpDivFim"> <label for="dataFim-{{uuid}}" class=" ">end</label> <input name="dataFim-{{uuid}" type="text " class="form-control fim dispDtp" readonly required style="position:relative;"> <small class="form-text text-muted "> <span class="dias">0</span><span> days</span> </small> </div> </div> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM