我在这些要求上花了一些时间,并通过 Telerik 的博客、论坛、演示、API 文档以及向他们的支持提交票证,我已经能够完成所有这些。它们比应有的更难,因为它们放置在调度程序的自定义编辑器中,这是一个局部视图,并且因为它们依赖于调度程序本身的触发事件。您需要的大部分信息都可以通过调度程序的事件传递,但困难在于找到有关它们的文档。我在编辑器中有 2 个 DateTimePickers,开始时间和结束时间:
<div data-container-for="start" class="k-edit-field">
@(Html.Kendo().DateTimePickerFor(model => model.Start)
.Name("start")
.HtmlAttributes(generateDatePickerAttributes("startDateTime", "start", "value:start"))
)
<span data-for="start" class="k-invalid-msg"></span>
</div>
<div class="k-edit-label">
@(Html.Label("End Time*"))
</div>
<div data-container-for="end" class="k-edit-field">
@(Html.Kendo().DateTimePickerFor(model => model.End)
.Name("end")
.HtmlAttributes(generateDatePickerAttributes(
"endDateTime",
"end",
"value:end",
new Dictionary<string, object>() { { "data-dateCompare-msg", "End date should be greater than or equal to the start date" } }))
)
<span data-for="end" class="k-invalid-msg"></span>
</div>
通过这种方法,他们被赋予了适当的剑道属性:
@functions{
public Dictionary<string, object> generateDatePickerAttributes(
string elementId,
string fieldName,
string dataBindAttribute,
Dictionary<string, object> additionalAttributes = null)
{
Dictionary<string, object> datePickerAttributes = additionalAttributes != null ? new Dictionary<string, object>(additionalAttributes) : new Dictionary<string, object>();
datePickerAttributes["id"] = elementId;
datePickerAttributes["name"] = fieldName;
datePickerAttributes["data-bind"] = dataBindAttribute;
datePickerAttributes["required"] = "required";
datePickerAttributes["style"] = "z-index: inherit;";
datePickerAttributes["data-role"] = "datetimepicker";
return datePickerAttributes;
}
}
为了使 DateTimePicker 反映营业时间,我订阅了调度程序Edit event
(不要忘记在调度程序事件规范中引用它),然后使用以下setOptions()
方法修改小部件:
function onEdit(e) {//When we open or add an event
var min = new Date(kendo.date.getDate(new Date()).getTime() + (kendo.date.MS_PER_HOUR * 9));
var max = new Date(kendo.date.getDate(new Date()).getTime() + (kendo.date.MS_PER_HOUR * 21));
e.container.find("[data-role=datetimepicker]").each(function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
});
}
您可以onChange()
使用以下代码将函数绑定到 DateTimePicker 本身,以强制结束时间始终反映 >= 开始时间,也在onEdit()
调度程序的方法中。它还处理在选择器中更改实际日期(不仅仅是时间)并使其保持在工作时间内的情况。如果没有这个位,最小时间仍然是您最初设置的任何时间,这意味着在第二天它将再次显示所有 24 小时。:
e.container.find("[name=start][data-role=datetimepicker]").bind("change", function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
var endTimePicker = $("#endDateTime").data("kendoDateTimePicker");
endTimePicker.value(widget.value());
endPicker = e.container.find("[name=end][data-role=datetimepicker]").getKendoDateTimePicker();
endPicker.timeView.setOptions({
max: max,
min: min
});
});
e.container.find("[name=end][data-role=datetimepicker]").bind("change", function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
});
检查重复预订并不像您想象的那么复杂,因为它不需要任何服务器调用、获取所有约会、检查时间范围和返回。Telerik 有一种在调度程序中检查约会的方法。这是一种他们不方便记录的方法:occurrencesInRange()
. 我在其中一个论坛演示中找到了它。您只需获取您想要使用的时间范围内的所有事件,如果没有其他人正在使用它,请预订该事件。如果是,您可以只显示警报。订阅调度程序的Save event
:
function scheduler_save(e) { if (!checkAvailability(e.event.start, e.event.end, e.event)) { alert("这个预约时间被占用了。安排一个不同的时间。"); e.preventDefault(); } } function checkAvailability(start, end, event) { var scheduler = $("#scheduler").getKendoScheduler();
var occurrences = scheduler.occurrencesInRange(start, end);
var idx = occurrences.indexOf(event);
if (idx > -1) {
occurrences.splice(idx, 1);
}
return !occurrences.length;
}
您可能遇到的另一个问题是 DateTimePicker 仅包含营业时间,但默认值为当天的 00:00:00,这当然超出了您的范围。这很难默认为营业时间开始,但您可以使用其他非常有用的方法执行以下操作event.isNew()
:
if (e.event.isNew()) {
var startdate = e.event.start;
startdate.setHours(9);
var start = e.container.find("[name=start][data-role=datetimepicker]");
var end = e.container.find("[name=end][data-role=datetimepicker]");
$(start).data("kendoDateTimePicker").value(startdate);
$(end).data("kendoDateTimePicker").value(startdate);
}
这是最后一组 JavaScript 方法:
function onEdit(e) {//When we open or add an event
var min = new Date(kendo.date.getDate(new Date()).getTime() + (kendo.date.MS_PER_HOUR * 9));
var max = new Date(kendo.date.getDate(new Date()).getTime() + (kendo.date.MS_PER_HOUR * 21));
if (e.event.isNew()) {
var startdate = e.event.start;
startdate.setHours(9);
var start = e.container.find("[name=start][data-role=datetimepicker]");
var end = e.container.find("[name=end][data-role=datetimepicker]");
$(start).data("kendoDateTimePicker").value(startdate);
$(end).data("kendoDateTimePicker").value(startdate);
}
e.container.find("[data-role=datetimepicker]").each(function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
});
e.container.find("[name=start][data-role=datetimepicker]").bind("change", function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
var endTimePicker = $("#endDateTime").data("kendoDateTimePicker");
endTimePicker.value(widget.value());
endPicker = e.container.find("[name=end][data-role=datetimepicker]").getKendoDateTimePicker();
endPicker.timeView.setOptions({
max: max,
min: min
});
});
e.container.find("[name=end][data-role=datetimepicker]").bind("change", function () {
var widget = $(this).getKendoDateTimePicker();
widget.timeView.setOptions({
max: max,
min: min
});
});
}
function scheduler_save(e) {
if (!checkAvailability(e.event.start, e.event.end, e.event)) {
alert("This appointment slot is taken. Schedule a different time.");
e.preventDefault();
}
}
function checkAvailability(start, end, event) {
var scheduler = $("#scheduler").getKendoScheduler();
var occurrences = scheduler.occurrencesInRange(start, end);
var idx = occurrences.indexOf(event);
if (idx > -1) {
occurrences.splice(idx, 1);
}
return !occurrences.length;
}
我希望这可以节省其他人花费我 20 个小时的时间。
资料来源:http ://www.telerik.com/forums/set-default-time-in-scheduler-editor-window-when-adding-task-in-month-view
http://docs.telerik.com/KENDO-UI/api/javascript/ui/datetimepicker#events
http://docs.telerik.com/KENDO-UI/api/aspnet-mvc/kendo.mvc.ui.fluent/schedulerbuilder
http://www.telerik.com/forums/how-to-check-for-double-reservations-overlap-(repeating-events)
Vladimir Illiev,Telerick DateTimePicker 专家