I'm having trouble trying to get my KendoUI Scheduler resources to populate correctly. I haven't found a good example of how to bind a nested JSON object (in this case Task and User listed in the screenshot) to resources that are fetched.
Also while running Fiddler, it seems like the resources listed below aren't even fetched from the web service. The documentation is super unclear on some of the specifics and I'm having a hard time finding the problem.
The schedule actually pulls back all the SchedulerEvents (the JSON fetched below) and shows me events bound to the Schedule properly, just they have no resources attached. Right now all of my webservice calls are running off localhost so JSONP shouldn't be required yet as my service calls are all calling "localhost".
I did find something similar to what I'm trying to do with projection of data here via Telerik's documentation, but I haven't been able to figure out a good solution yet.
Edited : updated my question with individual DataSource code
Edited 2 : I should also mention since posting this, the JSON screenshot isn't entirely accurate anymore as I've taken ScheduledTaskId and UserId (the two identifying properties of my Task and User resources I'm trying to add to appointments) and made that property available directly from my SchedulerEvent class to avoid nesting objects.
Javascript
//Datasources code has been moved to here. Explicitly fetching data and assigning to Resources datasource properties
$("#scheduler").kendoScheduler({
date: new Date("#DateTime.Now.ToShortDateString()"),
timezone: "Etc/UTC",
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
dataSource: {
batch: true,
transport: {
read: {
url: "ServiceURI/Schedule/Get",
dataType: "json"
},
update: {
url: "",
dataType: "json"
},
create: {
url: "",
dataType: "json"
},
destroy: {
url: "",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
resources: [
{
field: "userId",
title: "User",
dataTextField: "displayName",
dataValueField: "userId",
dataSource: userDataSource
}
{
field: "scheduledTaskId",
title: "Task",
dataTextField: "taskName",
dataValueField: "scheduledTaskId",
dataSource: taskDataSource
}
],
schema: {
model: {
id: "shiftId",
fields: {
shiftId: {
from: "ShiftId",
type: "number"
},
title: {
from: "Title",
validation: { required: true }
},
start: {
from: "Start",
type: "date",
validation: { required: true }
},
end: {
from: "End",
type: "date",
validation: { required: true }
},
scheduledTaskId: {
from: "ScheduledTaskId",
type: "number"
},
userId: {
from: "UserId",
type: "number"
},
description: {
from: "Description"
},
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
}
}
});
Datasources
var userDataSource = new kendo.data.DataSource({
transport: {
read: {
//This should be a customized list of users, or all users fetched from the datastore
url: "ServiceURI/UserProfile/Get/",
dataType: "json"
},
},
schema: {
model: {
id: "userId",
fields: {
userId: {
from: "UserId",
type: "number"
},
displayName: {
from: "DisplayName"
}
}
}
}
});
userDataSource.fetch();
var taskDataSource = new kendo.data.DataSource({
transport: {
read: {
//This should be the entire list of tasks fetched from the datastore
url: "ServiceURI/ScheduledTask/Get?companyId=1",
dataType: "json"
}
},
schema: {
model: {
id: "scheduledTaskId",
fields: {
scheduledTaskId: {
from: "ScheduledTaskId",
type: "number"
},
taskName: {
from: "TaskName"
}
}
}
}
});
taskDataSource.fetch();
JSON returned
Problem
The resources object is inside of the dataSource object as I thought it was supposed to be per the documentation
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
dataSource: {
resources: [
{
field: "userId",
title: "User",
dataTextField: "displayName",
dataValueField: "userId",
dataSource: userDataSource
}
{
field: "scheduledTaskId",
title: "Task",
dataTextField: "taskName",
dataValueField: "scheduledTaskId",
dataSource: taskDataSource
}
]
}
Answer
Just need to move the resources array outside of the DataSource... works as expected without any explicit .fetch() statements either
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
resources: [
{
field: "userId",
title: "User",
dataTextField: "displayName",
dataValueField: "userId",
dataSource: userDataSource
}
{
field: "scheduledTaskId",
title: "Task",
dataTextField: "taskName",
dataValueField: "scheduledTaskId",
dataSource: taskDataSource
}
],
dataSource: {
}
DataSource + Scheduler Creation
var userDataSource = new kendo.data.DataSource({
transport: {
read: {
//This should be a customized list of users, or all users fetched from the datastore
url: "ServiceURI/UserProfile/Get/",
dataType: "json"
},
},
requestEnd: function(e) {
//Start Fetching Task Data Source
taskDataSource.fetch();
},
schema: {
model: {
id: "userId",
fields: {
userId: {
from: "UserId",
type: "number"
},
displayName: {
from: "DisplayName"
}
}
}
}
});
Task DataSource declaration.
var taskDataSource = new kendo.data.DataSource({
transport: {
read: {
//This should be the entire list of tasks fetched from the datastore
url: "ServiceURI/ScheduledTask/Get?companyId=1",
dataType: "json"
}
},
requestEnd: function(e) {
//Once Task and User DataSource have been fetched, create the Scheduler
createScheduler(e);
},
schema: {
model: {
id: "scheduledTaskId",
fields: {
scheduledTaskId: {
from: "ScheduledTaskId",
type: "number"
},
taskName: {
from: "TaskName"
}
}
}
}
});
function createScheduler(e){
$("#scheduler").kendoScheduler({
date: new Date("#DateTime.Now.ToShortDateString()"),
timezone: "Etc/UTC",
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
dataSource: {
batch: true,
transport: {
read: {
url: "ServiceURI/Schedule/Get",
dataType: "json"
},
update: {
url: "",
dataType: "json"
},
create: {
url: "",
dataType: "json"
},
destroy: {
url: "",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
resources: [
{
field: "userId",
title: "User",
dataTextField: "DisplayName",
dataValueField: "UserId",
dataSource: userDataSource
}
{
field: "scheduledTaskId",
title: "Task",
dataTextField: "TaskName",
dataValueField: "ScheduledTaskId",
dataSource: taskDataSource
}
],
schema: {
model: {
id: "shiftId",
fields: {
shiftId: {
from: "ShiftId",
type: "number"
},
title: {
from: "Title",
validation: { required: true }
},
start: {
from: "Start",
type: "date",
validation: { required: true }
},
end: {
from: "End",
type: "date",
validation: { required: true }
},
scheduledTaskId: {
from: "ScheduledTaskId",
type: "number"
},
userId: {
from: "UserId",
type: "number"
},
description: {
from: "Description"
},
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
}
}
});
}
Start the DataSources fetching from User Source then Task Source and finally creation of the Scheduler.
userDataSource.fetch();
I have never tried this before, but I think above would work as per your requirement.
I think your issue is binding Case. In your Datasources for the resource Objects, you have a model definition, taking items from your JSON data and transforming it into a Model:
var userDataSource = new kendo.data.DataSource({
transport: {
read: {
//This should be a customized list of users, or all users fetched from the datastore
url: "ServiceURI/UserProfile/Get/",
dataType: "json"
},
},
schema: {
model: {
id: "userId",
fields: {
userId: {
from: "UserId",
type: "number"
},
displayName: {
from: "DisplayName"
}
}
}
}
});
In your scheduler Binding, you are setting the dataTextField and dataValueField to:
{
field: "userId",
title: "User",
dataTextField: "DisplayName",
dataValueField: "UserId",
dataSource: userDataSource
}
Notice that your model is displayName and userId, but your resource Bindings are DisplayName and UserId - By the time you are binding into the Scheduler resource collection, the data has been transformed into your model schema, and casing is important.
If you correct the casing, that should solve your issue. You will also need to ensure that both Datasources are populated prior to creating the Scheduler object.
Related
I define a grid in my page :
<div id="grid"></div>
<script>
$(document).ready(function () {
var crudServiceBaseUrl = "http://demos.kendoui.com/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Grid/GetPerson",
dataType: "json",
contentType: 'application/json; charset=utf-8',
type: 'Get'
},
update: {
url: function (person) {
debugger;
return "/Grid/Update";
},
contentType: 'application/json; charset=utf-8',
type: "POST",
},
destroy: {
url: crudServiceBaseUrl + "/Products/Destroy",
dataType: "jsonp"
},
create: {
url: crudServiceBaseUrl + "/Products/Create",
dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false, nullable: true },
Name: { validation: { required: true } },
Family: { validation: { required: true, min: 1 } },
Tel: {}
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
{ field: "Name", title: "نام" },
{ field: "Family", title: "فامیل" },
{ field: "Tel", title: "تلفن", width: "100px" },
{ command: [{ name: "edit", text: "ویرایش" }, { name: "destroy", text: "حذف" }], title: "عملیات", width: "160px" }],
messages: {
editable: {
cancelDelete: "لغو",
confirmation: "آیا مایل به حذف این رکورد هستید؟",
confirmDelete: "حذف"
},
commands: {
create: "افزودن ردیف جدید",
cancel: "لغو کلیهی تغییرات",
save: "ذخیرهی تمامی تغییرات",
destroy: "حذف",
edit: "ویرایش",
update: "ثبت",
canceledit: "لغو"
}
},
editable: "popup"
});
});
In person parameter in update function, i can access changed row by :
person.models[0]
it gives me :
Object {ID:1,Name:"pejman",Family:"kam",Tel:"098787887"}
SO i want to send this data to the server, so i have a action in GridController:
[HttpPost]
public void Update(TblPerson person)
{
//do update
}
for doing it, i try :
url: function (person) {
return "/Grid/Update/" + JSON.stringify(person.models[0])
},
in the update method, but it doesn't work, how can i do it?
NOTE: when i using above in Network tab of browser give me Bad Reuest error:
URL:http://localhost:2145/Grid/Update/%7B%22ID%22:1,%22Name%22:%22pejman%22,%22Family%22:%22kam%22,%22Tel%22:%22098787878%22%7D
Status Code:400 Bad Request
The problem is that kendo.stringify(options.models) sends your object in JSON string. So I believe that your js code can stay as it is. Just change your Update method in controller to something like:
[HttpPost]
public void Update(string models)
{
var values = JsonConvert.DeserializeObject<IEnumerable<TblPerson>>(models);
foreach (var value in values)
{
//Your action
}
}
The approach above just assume that you can send more models to update. Don't forget using Newtonsoft.Json
I want to populate the Kendo TreeView in which 2 nodes are local dataSource and the last node should be remote Datasource
Here is my code:
$("#AftermarketTreeView").kendoTreeView({
dataTextField: ["text", "text", "MC_ANALYSIS_NAME"],
dataSource: {
data: [
{
text: "Initiate",
items: [
{ text: "Parts Selection", haschildren: false },
{ text: "Assumptions", haschildren: false },
{ text: "Team", haschildren: false },
]
},
{
text: "Analyze",
items: [
{ text: "Part Attributes", haschildren: false },
{ text: "Aftermarket Evaluation", haschildren: false }
]
},
{
text: "Monto Carlo",
items: [
{ text: "Monto Carlo", haschildren: true }
]
}
],
schema: {
model: {
hasChildren: "items",
children: {
schema: {
data: "items",
model: {
hasChildren: "haschildren",
children: {
schema: {
// override the schema.data setting from the parent
data: function (response) {
return response;
}
},
transport: {
read: {
url: ResolveUrl("/CreateMaintainAnalysis/GetMontoCarloData/"),
dataType: "jsonp",
data:onDataSendAnalysisID,
}
},
}
}
}
}
}
}
}
});
Using above code I am getting structure as below
Where Initiate and Analyze are Local DataSource and Monto Carlo is Remote DataSource but I don't want the node again to be Monto Carlo under it that should be the direct remote DataSource from Database
so help me in this to solve
Thanks in Advance!!!
you can change your read property to a function:
read: function(options) { /* here you can do the ajax call for the remote dataSource and then you can merge the local dataSource with the remote dataSource, you can create a new array to accomplish this. */ }
You can see a example in here.
The idea is to use options.success(result); the result is the merged dataSource (remote and local).
I use telerik scheduler in html+js. My code is:
$(document).ready(function () {
kendo.culture("pl-PL");
$("#scheduler").kendoScheduler({
date: new Date("2016/3/4"),
startTime: new Date("2016/3/4 07:00"),
views: [
"day",
{ type: "workWeek", selected: true },
"week",
"month"
],
timezone: "Europe/Warsaw",
dataSource: {
batch: true,
transport: {
read: {
url: "../Meetings/Read",
dataType: "jsonp"
},
update: {
url: "http://demos.telerik.com/kendo-ui/service/tasks/update",
dataType: "jsonp"
},
create: {
url: "http://demos.telerik.com/kendo-ui/service/tasks/create",
dataType: "jsonp"
},
destroy: {
url: "http://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: "ID",
fields: {
ID: { from: "MeetingID" ,type: "number" },
title: { from: "Title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "Start" },
end: { type: "date", from: "End" },
description: { from: "Description" },
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
ownerId: { from: "OwnerID", defaultValue: 1 },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
},
filter: {
logic: "or",
filters: [
{ field: "ownerId", operator: "eq", value: 1 },
{ field: "ownerId", operator: "eq", value: 2 }
]
}
},
resources: [
{
field: "ownerId",
title: "Owner",
dataSource: [
{ text: "Alex", value: 1, color: "#f8a398" },
{ text: "Bob", value: 2, color: "#51a0ed" },
{ text: "Charlie", value: 3, color: "#56ca85" }
]
}
]
});
});
Like you see I've changed culture of scheluder (date and time format, names of days, months etc.) and timezone. All of my tasks are disappear. If I removed first line (kendo.culture("pl-PL")) tasks will be shown.
How can I work with changing culture and timezone in the same time? It's even posiible?
Edit
My sample value returned by controller is:
{"MeetingID":1,"Start":"2016-03-01T08:30:00","End":"2016-03-01T07:30:00","Title":"Testowe","Description"
:"ASD","OwnerID":1,"IsAllDay":false,"RecurrenceRule":"","RecurrenceID":1,"RecurrenceException":"","StartTimezone"
:"","EndTimezone":""}
Have you Included the file kendo.timezones.min.js ?
If not then you have to add (in your header html section)the following line
<script src="http://kendo.cdn.telerik.com/2016.1.112/js/kendo.timezones.min.js"></script>
You can find a working sample here http://dojo.telerik.com/udAyo
I have a Kendo UI grid, that will only display values like [object object] even if the type is "string". I have the datasource for the grid working with a graph, so I know there is data, and that it should be showing other values.
I'm using MVVM
Datasource:
var dataSource = new kendo.data.DataSource({
type: "everlive",
autoSync: true,
serverFiltering: true,
filter: {
field: "DeviceID",
operator: "eq",
value: device.uuid
},
transport: {
// binding to the Order type in Everlive
typeName: "BreakPoint"
},
schema: {
model: {
id: "Id",
fields: {
// default Everlive fields
CreatedBy: {
type: "string"
},
CreatedAt: {
type: "date"
},
ModifiedAt: {
type: "date"
},
// type fields
Energi: {
type: "number"
},
Note: {
type: "string"
},
activity_green: {
type: "bool"
},
activity_yellow: {
type: "bool"
},
activity_red: {
type: "bool"
}
}
}
}
});
HTML:
<div data-role="grid"
data-theme="silver"
date-scrollable="true"
data-pageable="true"
data-columns="[
{ 'field': 'CreatedAt', template:'#= formatAddress(data) #'},
{ 'field': 'Note' },
{ field: 'Energi', format:'{0:c}'},
{ field: 'activity_green', title: 'Grøn Aktivitet', format:'{0:c}'},
{ field: 'activity_yellow', title: 'Gul Aktivitet', format:'{0:c}'},
{ field: 'activity_red', title: 'Rød Aktivitet', format:'{0:c}'}
]"
data-bind="source: ds"
style="height: 200px"></div>
I have looked at an example Kendo grid here, and another one on Codeproject and a thread on this site, but I don't seem to find the error. I'm not very knowledgeable with javascript or HTML, so I expect it to be a simple mistake on my part.
Here is the code I have so far:
$(document).ready(function () {
var baseURL = "/api/LeaveTypes",
leaveTypes = new kendo.data.DataSource({
autoSync: true,
transport: {
read: {
url: baseURL + "?getAll=true",
dataType: "jsonp",
type: "GET"
},
update: {
url: baseURL,
dataType: "jsonp",
type: "POST"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
schema: {
model: {
id: "Id",
fields: {
Id: {type: "number", editable: false, validation: { required: true } },
Description: { type: "string", editable: false, validation: { required: true } },
IsEssLeaveType: { type: "boolean", editable: true, },
ColourRGB: {type: "string", editable: true, nullable: true }
}
}
}
});
$(".leavetypesgrid").kendoGrid({
dataSource: leaveTypes,
toolbar: ["save"],
columns: [{
field: "Id",
title: "Leave Type ID"
}, {
field: "Description",
title: "Leave Type"
}, {
field: "IsESSLeaveType",
template: '<input type="checkbox" #= IsESSLeaveType ? "checked=checked" : "" # ></input>',
title: "Flagged for ESS",
}, {
field: "ColourRGB",
title: "Colour"
}
],
scrollable: false,
editable: {
update: true
}
});
});
I am trying to get it to work in JSFiddle, but since I'm quite new to it, I'm still struggling to get the data source disconnected from the Controller that I'm currently using to populate the grid with, and connecting it to sample data.
Here is the Controller's Post method:
public SimpleResult Post(List<LeaveCalendarLeaveType> leaveTypesList)
{
return ESSLeaveDataManager.SaveLeaveTypes(leaveTypesList);
}
Any help will be much appreciated! :)
The first thing that I noticed is that you have two data sources defined. One called dataSource and another called leaveTypes. You are only setting the datasource on your grid to leaveTypes.
Did you configure your MVC route so that it goes to the action named Post() when /api/LeaveTypes is called? Otherwise, the url for the update config should be /api/LeaveTypes/Post