Related
I want to show day in shift for example 24 days hours can be divided into 3 shift 8 hours each or can 6 hours each.
Against that i wanted to add events in Kendo Scheduler. Each day must have shift as show in below image
in the image shift marked for each day and noted with different color.
Each shift can or can not have events.
I'm also expecting functionality where events can move across the shifts.
I believe you'll have to implement a custom view to accomplish this. Here is a Telerik page that demonstrates it, and if you click the "Open in Dojo" link in the upper right of the code example you can see it execute (and edit and try it yourself).
Code example for their custom 3-day view from link
<div id="scheduler"></div>
<script>
var CustomAgenda = kendo.ui.AgendaView.extend({
endDate: function() {
var date = kendo.ui.AgendaView.fn.endDate.call(this);
return kendo.date.addDays(date, 31);
}
});
var ThreeDayView = kendo.ui.MultiDayView.extend({
nextDate: function () {
return kendo.date.nextDay(this.startDate());
},
options: {
selectedDateFormat: "{0:D} - {1:D}"
},
name: "ThreeDayView",
calculateDateRange: function () {
// Create a range of dates that will be displayed within the view.
var start = this.options.date,
idx, length,
dates = [];
for (idx = 0, length = 3; idx < length; idx++) {
dates.push(start);
start = kendo.date.nextDay(start);
}
this._render(dates);
}
});
$(function() {
$("#scheduler").kendoScheduler({
date: new Date("2013/6/13"),
startTime: new Date("2013/6/13 07:00 AM"),
height: 600,
views: [
"day",
"week",
// "custom week",
{ type: "ThreeDayView", title: "Three day view", selected: true },
// "custom agenda",
{ type: "CustomAgenda", title: "Custom Agenda" }
],
timezone: "Etc/UTC",
dataSource: {
batch: true,
transport: {
read: {
url: "https://demos.telerik.com/kendo-ui/service/tasks",
dataType: "jsonp"
},
update: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/update",
dataType: "jsonp"
},
create: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/create",
dataType: "jsonp"
},
destroy: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/destroy",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
schema: {
model: {
id: "taskId",
fields: {
taskId: { from: "TaskID", type: "number" },
title: { from: "Title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "Start" },
end: { type: "date", from: "End" },
startTimezone: { from: "StartTimezone" },
endTimezone: { from: "EndTimezone" },
description: { from: "Description" },
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
ownerId: { from: "OwnerID", defaultValue: 1 },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
}
}
});
});
</script>
I have a scheduler and a dropdown in a diary app. The scheduler is configured as such:
$("#scheduler").kendoScheduler({
date : Date.now(),
workDayStart: new Date("2015/1/1 08:00 AM"),
workDayEnd: new Date("2015/1/1 8:00 PM"),
dateHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'ddd dd/M')#</strong>"),
majorTimeHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'HH')#</strong><sup>00</sup>"),
minorTimeHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'HH')#</strong><sup>#=kendo.toString(date, 'mm')#</sup>"),
selectable: true,
messages: {
ariaSlotLabel: "Selected from {0:g} to {0:g}",
showWorkDay: "Show core work hours"
},
editable: {
window: {
title: "Work Request Details",
width: "800px"
},
template: $("#customEditorTemplate").html()
},
edit: function (e) {
//set the start end datetime
if (e.event.isNew && e.event.id == -1) {
var startDtp = e.container.find("[name=start][data-role=datetimepicker]");
var endDtp = e.container.find("[name=end][data-role=datetimepicker]");
var setStartDate = e.event.start;
var setEndDate = e.event.end;
setStartDate.setHours(8);
setEndDate.setHours(-6); // by default the end date is midnight on the following day of the selected cell so we subtract 6h to get 18:00 on the selected date.
$(startDtp).data("kendoDateTimePicker").value(setStartDate); //set start date to the selected cell start date and time 08:00
$(endDtp).data("kendoDateTimePicker").value(setEndDate); //set enddate to the selected cell end date and time 18:00
}
var recurrenceEditor = e.container.find("[data-role=recurrenceeditor]").data("kendoRecurrenceEditor");
//set start option value, used to define the week 'Repeat on' selected checkboxes
recurrenceEditor.setOptions({
start: new Date(e.event.start)
});
},
eventTemplate: $("#eventTemplate").html(),
height: 550,
messages: {
allDay: "Anytime"
},
views: [
{ type: "day", allDaySlot: true},
{ type: "week", eventHeight: 80 },
{ type: "timeline", eventHeight: 80 },
{ type: "timelineWeek", selected: true, majorTick: 1440, minorTickCount: 1, eventHeight: 80 },
{ type: "agenda" },
{ type: "month", eventHeight: 80 }
],
timezone: "Etc/UTC",
selectable: true,
dataSource: {
parameterMap: function parameterMap(data, type) {
console.log(type);
if (type === "read") {
//var reqFilter = wRequestFilter.value();
var reqFilter = 'ALL'
console.log(reqFilter);
if (reqFilter == "MY") {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }, { field: "AssigneeID", operator: "eq", value: 1 }] };
} else if (reqFilter == "ALL") {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }] };
} else {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }, { field: "team", operator: "eq", value: reqFilter }] };
}
}
console.log(data);
return data;
},
type: "signalr",
push: function (e) {
generateNotification(e.type, e.items[0].WRequestID, e.items[0].diary, e.items[0].team);
},
transport: {
signalr: {
hub: sHub,
promise: sHubStart,
server: {
read: "read",
create: "create",
update: "update",
destroy: "destroy"
},
client: {
read: "read",
create: "create",
update: "update",
destroy: "destroy"
}
},
},
schema: {
model: {
id: "WRequestID",
fields: {
WRequestID: {
type: "number",
editable: false,
defaultValue: -1
},
start: {
from: "Start",
type: "date",
culture: "en-GB"
},
end : {
from: "End",
type: "date",
culture: "en-GB" },
diary: {
from: "Diary",
type: "string",
defaultValue: "#AppShort"
},
team: {
from: "Team",
type: "string",
validation: { required: true }
},
title: {
from: "Title",
type: "string",
validation: { required: true }
},
workManager: {
from: "WorkManagerID",
type: "number",
validation: { required: true }
},
assignee: {
from: "AssigneeID",
type: "number",
validation: { required: true }
},
changeRef: {
from: "ChangeRef",
type: "string",
validation: { required: true }
},
description: {
from: "Description",
type: "string",
validation: { required: true }
},
impactedServers: {
from: "ImpactedServers",
type: "string",
validation: { required: true }
},
impactedServices: {
from: "ImpactedServices",
type: "string",
validation: { required: true }
},
isBAU: {
from: "IsBAU",
type: "boolean",
defaultValue: false
},
projectRef: {
from: "ProjectRef",
type: "string",
validation: { required: true }
},
notes: {
from: "Notes",
type: "string"
},
isOOH: {
from: "IsOOH",
type: "boolean",
defaultValue: false
},
isAllDay: {
from: "IsAllDay",
type: "boolean",
defaultValue: false
},
recurrenceRule: {
from: "RecurrenceRule",
type: "string"
},
recurrenceId: {
from: "RecurrenceID",
type: "number"
},
recurrenceException: {
from: "RecurrenceException",
type: "string"
},
startTimezone: {
from: "StartTimezone",
type: "string"
},
endTimezone: {
from: "EndTimezone",
type: "string"
},
requestStatus: {
from: "RequestStatus",
type: "number",
defaultValue: 0
}
}
},
},
}
});
I am trying to use parameterMap to filter the data based on one or two bits of data.
If the dropdown value = ALL then the data is filtered by diary =
#AppShort where #AppShort is derived from the web.config settings
section.
If the dropdown value = MY then the data is further filtered to just
display the current uses events
If the dropdown value is anything else then that means a team name is
selected and so the data is filtered by diary and team.
My problem is that the data is not filtered at all and the parameterMap function is never triggered. Is this the best approach or is there another way of implementing filtering.
Any help appreciated.
UPDATE
As requested... this is my signalR hub code:
Public Class WRequestHub
Inherits Hub
Private requestService As SchedulerRequestService
Public Sub New()
requestService = New SchedulerRequestService()
End Sub
Public Function Read() As IEnumerable(Of WRequestViewModel)
Return requestService.GetAll()
End Function
Public Sub Update(request As WRequestViewModel)
requestService.Update(request)
Clients.Others.update(request)
End Sub
Public Sub Destroy(request As WRequestViewModel)
requestService.Delete(request)
Clients.Others.destroy(request)
End Sub
Public Function Create(request As WRequestViewModel) As WRequestViewModel
requestService.Insert(request)
Clients.Others.create(request)
Return request
End Function
Public Sub LockRecord(id As Integer)
Clients.Others.lockRecord(New With {
Key .id = id
})
End Sub
Public Sub UnlockRecord(id As Integer)
Clients.Others.unlockRecord(New With {
Key .id = id
})
End Sub
End Class
And this is my SchedulerRequestService class...
Public Class SchedulerRequestService
Public Overridable Function GetAll() As IQueryable(Of WRequestViewModel)
Using de As New SupportDiaryEntities
Dim rList As IQueryable(Of WRequestViewModel)
rList = (From r In de.tWorkRequests
Select New WRequestViewModel() With {
.WRequestID = r.WRequestID,
.Start = r.Start,
.[End] = r.[End],
.Title = r.Title,
.Diary = r.Diary,
.Team = r.Team,
.WorkManagerID = r.WorkManagerID,
.AssigneeID = r.AssigneeID,
.ChangeRef = r.ChangeRef,
.Description = r.Description,
.ImpactedServers = r.ImpactedServers,
.ImpactedServices = r.ImpactedServices,
.IsBAU = r.IsBAU,
.ProjectRef = r.ProjectRef,
.Notes = r.Notes,
.IsOOH = r.IsOOH,
.IsAllDay = r.IsAllDay,
.RecurrenceRule = r.RecurrenceRule,
.RecurrenceID = r.RecurrenceID,
.RecurrenceException = r.RecurrenceException,
.StartTimezone = r.StartTimezone,
.EndTimezone = r.EndTimezone,
.RequestStatus = r.RequestStatus
}).ToList.AsQueryable()
Return rList
End Using
End Function
'OTHER FUNCTIONS (Insert, Update, Delete) Removed for brevity.
End Class
UPDATE 2
With some help from Calinaadi and examples of filtering a SignalR datasource on a Kendo Grid I can see that I need to modify my read function to accept my filter(s). Unfortunately the examples used with the grid had .take, .skip, .sort, .filter and .aggregate as paramenters which I understand when you have a grid with paging and you want to take X records after skipping Y records.
This is a typical example from telerik demos...
public DataSourceResult Read(MyDataSourceRequest request)
{
return productService.Read().ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter, request.Aggregates);
}
For a scheduler I would expect a read to fetch back all events with an end on or after the start of the current scheduler view and a start on or before the end of the current scheduler view. Probably sorted by start. Filtered by the field filters is necessary (these are the filters I've set). I can't see take, skip or aggregate have any concept in fetching event data.
My app function completely apart from the filtering. I have a VS solution I can share if necessary with database populated with dummy records.
Offering a bounty for any help.
You should change:
transport: {
signalr: {
hub: sHub,
promise: sHubStart,
ParameterMap: "parameterMap",
to:
transport: {
parameterMap: function parameterMap(data, type) {
alert(type);
},
signalr: {
After many searches and much reading. I now have a working system. The scheduler required the parameter serverFiltering: true also the Read, Create, Update and Destroy functions has to be redone to accept the filter that was posted. If anyone would like a copy of the code which is a tad too much to post here I can let you have it.
I have a field on my kendo ui grid which uses an editor:
columns:[{ field:"Nome", title: "Nome" },{ field: "idTipoQuarto", title:"Tipo de Quarto", editor: tipoQuartoEditor},
In my model i have:
schema:
{
data: "data",
total: function(response)
{
return $(response.data).length;
},
model:
{
id: "idQuarto",
fields:
{
idQuarto: { editable: false, nullable: true },
Nome: { validation: { required: true } },
idTipoQuarto: { validation: { required: true }}
}
}
}
And my editor function is:
function tipoQuartoEditor(container, options)
{
$('<input data-text-field="Nome" data-value-field="Nome" data-bind="value:' + options.field + '"/>').appendTo(container).kendoDropDownList({
autoBind: false,
dataSource: new kendo.data.DataSource({
transport:
{
read:
{
url: "data/quartos.php",
},
parameterMap: function(options, operation)
{
if (operation !== "read" && options.models)
{
return {models: kendo.stringify(options.models)};
}
}
},
schema:
{
data: "data",
model:
{
id: "idTipoQuarto",
value: "Nome"
}
}
})
});
}
I can see the values when my popup is opened in the drop-down list, and i can post the selections to my database when clicking on the update/insert button, but the popup won´t disappear. It shows me an error that i don´t understand:
Object {xhr: Object, status: "parsererror", errorThrown: SyntaxError: Unexpected token A, sender: ht.extend.init, _defaultPrevented: false…}
What am i missing here, i have seen another post but with no luck adapting to my problem.
Anyone?
Thanks for your time, regards
I have a kendo UI scheduler that makes a ajax call and receives 2 json records through the read method. This is my scheduler widget.
$("#scheduler").kendoScheduler({
date: new Date(),
startTime:time ,
height: kendo.support.mobileOS.wp ? "28em" : 600,
views: [
{ type: "day", selected: true },
{ type: "week", selectedDateFormat: "{0:ddd,MMM dd,yyyy} - {1:ddd,MMM dd,yyyy}" },
"month",
{ type: "agenda", selectedDateFormat: "{0:ddd, M/dd/yyyy} - {1:ddd, M/dd/yyyy}" },
],
mobile: "phone",
datasource:{
batch: true,
transport: {
read: {
url: "http://mydomain.com/api/Schedule/Tasks_Read",
dataType: "jsonp"
},
update: {
url: "http://demos.telerik.com/kendo-ui/service/meetings/update",
dataType: "jsonp"
},
create: {
url: "http://demos.telerik.com/kendo-ui/service/meetings/create",
dataType: "jsonp"
},
destroy: {
url: "http://demos.telerik.com/kendo-ui/service/meetings/destroy",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
schema: {
data:"Data",
model: {
id: "AppointmentId",
fields: {
//meetingID: { from: "MeetingID", type: "number" },
title: { from: "Title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "Start" },
end: { type: "date", from: "End" },
startTimezone: { from: "StartTimezone" },
endTimezone: { from: "EndTimezone" },
description: { from: "Description" },
//recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
//roomId: { from: "RoomID", nullable: true },
//atendees: { from: "Atendees", nullable: true },
isAllDay: { type: "boolean", from: "IsAllDay" },
//professionalId:{type:"string", from: "ProfessionalId", defaultValue=""},
//professionalName:{type:"string", from: "ProfessionalName"},
//clientId:{type:"string", from: "ClientId", defaultValue=""},
//clientName:{type:"string", from: "ClientName"}
}
}
}
}
})
I have 2 problems
the problem is that the records are not displayed on the scheduler
When i un-comment out my custom properties in the schema design the code when i compile the code it errors.
UPDAE
The json server response looks like
"{\"AppointmentId\":30,\"ClientId\":\"b26d9cc1-ddcc-4277-a4eb-61835c83fb48\",\"ClientName\":\"beast client\",\"ProfessionalId\":\"260f0c43-7ff9-4654-af2b-5df2f5b8d6a1\",\"ProfessionalName\":\"AutoFirstName AutoLastName\",\"Start\":\"2014-03-30T07:00:00\",\"End\":\"2014-03-30T07:30:00\",\"ColorUsed\":null,\"HairStyleId\":null,\"Title\":\"beast client Haircut \",\"Description\":\"beast client Haircut\",\"InactiveReasonDate\":null,\"InactiveReasonId\":null,\"IsAllDay\":false,\"StartTimezone\":null,\"EndTimezone\":null,\"RecurrenceRule\":null,\"RecurrenceException\":null,\"ClientRating\":null},{\"AppointmentId\":31,\"ClientId\":\"b26d9cc1-ddcc-4277-a4eb-61835c83fb48\",\"ClientName\":\"beast client\",\"ProfessionalId\":\"260f0c43-7ff9-4654-af2b-5df2f5b8d6a1\",\"ProfessionalName\":\"AutoFirstName AutoLastName\",\"Start\":\"2014-03-31T07:00:00\",\"End\":\"2014-03-31T07:30:00\",\"ColorUsed\":null,\"HairStyleId\":null,\"Title\":\"beast client Haircut\",\"Description\":\"beast client Haircut \",\"InactiveReasonDate\":null,\"InactiveReasonId\":null,\"IsAllDay\":false,\"StartTimezone\":null,\"EndTimezone\":null,\"RecurrenceRule\":null,\"RecurrenceException\":null,\"ClientRating\":null}"
Main Problem
My current problem is the refresh progress when updating a grid datasource. I have change my code use the kendo.ui.progress in that way when requestStart event starts I ser the kendo.ui.progress to true. This activates the loading image when it end it calls the requestEnd.
The problem is that this event is hapenning for sorting and filtering. And I want it to only trigger for the read function of the dataSource. This problem makes the grid to use the progress endlessly.
Is there some way to filter in the requestStart and requestEnd only activate on the transport read?
My DataSource Code
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: url_Obtener_Periodo,
type: "POST"
},
parameterMap: function (options, operation) {
if (operation == "read" && options) {
return {
"periodo.Year": $("#periodo-anio").val(),
"periodo.Month": $("#periodo-mes").val(),
"Filtro": $("#Filtro").val()
};
}
}
},
requestStart: function (e) {
kendo.ui.progress($("#grid-container"), true);
},
requestEnd: function (e) {
kendo.ui.progress($("#grid-container"), false);
},
schema:{
model: {
id: "Codigo_De_Pedido",
fields: {
Codigo_De_Pedido: { type: "number" },
Fecha_Y_Hora_De_Creacion: { type: "date" },
UserName: { type: "string" },
Nombre_Del_Usuario: { type: "string" },
Codigo_Del_Vendedor: { type: "number" },
Nombre_Del_Vendedor: { type: "string" },
Is_Pedido_Closed: { type: "bool" },
Estado: { type: "string" }
}
}
},
pageSize: 10
});
The changes I did to solve the progress endlessly problem where 2.
Removing requestEnd function from the dataSource
Adding dataBound function to the Grid
Data Source Code
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: url_Obtener_Periodo,
type: "POST"
},
parameterMap: function (options, operation) {
if (operation == "read" && options) {
return {
"periodo.Year": $("#periodo-anio").val(),
"periodo.Month": $("#periodo-mes").val(),
"Filtro": $("#Filtro").val()
};
}
}
},
schema:{
model: {
id: "Codigo_De_Pedido",
fields: {
Codigo_De_Pedido: { type: "number" },
Fecha_Y_Hora_De_Creacion: { type: "date" },
UserName: { type: "string" },
Nombre_Del_Usuario: { type: "string" },
Codigo_Del_Vendedor: { type: "number" },
Nombre_Del_Vendedor: { type: "string" },
Is_Pedido_Closed: { type: "bool" },
Estado: { type: "string" }
}
}
},
pageSize: 10,
requestStart: function (e) {
kendo.ui.progress($("#grid-container"), true);
}
});
Kendo Grid Code
kendoGrid = $("#selectable-pedidos").kendoGrid({
dataSource: dataSource,
pageable: true,
sortable: true,
filterable: {
extra: false,
operators: {
string: {
startswith: "Comienza Con",
eq: "Es Igual A",
neq: "No Es Igual A"
}
}
},
dataBound: function (e) {
kendo.ui.progress($("#grid-container"), false);
},
columns: [
{ field: "Fecha_Y_Hora_De_Creacion", title: "Fecha y Hora", template: "#= kendo.toString(Fecha_Y_Hora_De_Creacion, 'dd/MM/yyyy hh:mm:ss tt') #" },
{ field: "Codigo_De_Pedido", title: "Código de Pedido" },
{ field: "Estado", filterable: true, title: "Estado" },
{ field: "Codigo_Del_Vendedor", title: "Código de Vendedor" },
{ field: "Nombre_Del_Vendedor", title: "Nombre de Vendedor" },
{
command: {
text: "Ver Detalle de Pedido",
click: function (e) {
$("#empty").append("<form method='POST' action='/HojaDeRuta/GetById/'><input type='hidden' name='Codigo_Pedido' value='"
+ this.dataItem($(e.currentTarget).closest("tr")).Codigo_De_Pedido + "' /><input type='submit' /></form>");
$("#empty input[type='submit']").click();
}
},
title: " "
}
]
}).data("kendoGrid");
There are a few things about your questions worth mentioning for those who read this:
Is there some way to filter in the requestStart and requestEnd only
activate on the transport read?
Yes, but it will not help you. The parameter of the event has a type property that will contain read, update, destroy or create.
statementEntriesDS.bind("requestStart", function (e) {
switch (e.type) {
case "create":
alert('-> event, type "create".');
break;
case "read":
alert('-> event, type "read".');
break;
case "update":
alert('-> event, type "update".');
break;
case "destroy":
alert('-> event, type "destroy".');
break;
}
});
Your example code doesn't specify serverFiltering or serverSorting so sorting and filtering wouldn't cause an remote action. You'll only get client-side sorting and filtering. However, if they are specified they're all going to result in a read and that wouldn't really help you.
That you would not have the requestEnd event fire sounds odd. You should probably add a handler for the error event and see if something is failing.
If you really want complete control over what's happening, you can specify a function for your read:
transport: {
read: function (options) {
kendo.ui.progress($gridContainer, true);
$.ajax({
url: carrierServiceBaseUrl + "/GetManualStatementsCarrierList",
contentType: 'application/json; charset=utf-8',
dataType: "json",
type: "POST",
success: function (result) {
// notify the data source that the request succeeded
options.success(result);
kendo.ui.progress($gridContainer, false); },
error: function (result) {
options.error(result); // Call the DataSource's "error" method with the results
kendo.ui.progress($gridContainer, false);
notification.show({
title: "ERROR:",
message: result.statusText
}, "error");
}
});
}
}