Hi all,
I am rather new to JS and Kendo UI and I am trying to hook up a Kendo UI Grid to a sharepoint list via the Sharepoint REST Interface.
So far I have set up a datasource for read, create, update and destroy and it is working like charm. My biggest issue I have are the different Sharepoint field types.
CRUD operations for simple text, date, number fields are working without an issue. But I don't understand how to implement fields like choice filelds, lookupfields, people and groups fields. Can somebody show me an working example how to properly display a people-and-groups column in the grid and how to edit it? Same for a choice field.
Many thanks in adavance.
9 Answers, 1 is accepted
Kendo UI does not have dedicated SharePoint UI widgets, like people list but you can implement one yourself relatively easy using the available widgets like dropdown and popup.
More information on how to add custom editors to the grid can be found in the documentation.
Regards,
Genady Sergeev
Progress Telerik

Hi,
I have found some articles from Ed Musters but he stopped the article series just at the point where it got interesting :-(
As I am still new to JavaScript and I would like to demonstrate Kendo UI to one of our customers I ask you guys once more for help. Has anybody a working example for:
Using DataGrid to read/create/update/delete Data from a Sharepoint-Online list with all kinds of column types (e.g. People column, choice column, Single line of text, etc)
Many thanks in advance.
Best regards
Currently, we have only the examples made by Ed Musters.
When doing CRUD operation with the Grid there are no further specifics when using the SharePoint, the main point is to return or to parse the response in the expected from the Grid dataSource format:
https://docs.telerik.com/kendo-ui/framework/datasource/crud
For example, the transport can be set a function and the parsed values can be set vie options.success:
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read
<script>
var
dataSource =
new
kendo.data.DataSource({
transport: {
read:
function
(options) {
// make JSONP request to https://demos.telerik.com/kendo-ui/service/products
$.ajax({
dataType:
"jsonp"
,
// "jsonp" is required for cross-domain requests; use "json" for same-domain requests
success:
function
(result) {
// notify the data source that the request succeeded
options.success(result);
},
error:
function
(result) {
// notify the data source that the request failed
options.error(result);
}
});
}
}
});
dataSource.fetch(
function
() {
console.log(dataSource.view().length);
// displays "77"
});
</script>
Regards,
Stefan
Progress Telerik

Hi,
I am getting closer to understand to what I am doing :-). Please have a look at my code below. Looking at my response (response without model.png) does my code (especially the model part) make sense?
When you have a look at the picture "response model.png" you can see that the model inserted a field "MyNewColumn". But I can't see the field "SomeotherInformation" within the Author object. Is this the expected behavior?
Please let me know if you have any comments for my code. Thanks in advance.
var
grid = $(
"#kendoGrid1"
).kendoGrid({
height: 200,
columns: [{
title:
"Author"
,
field:
"Author.Title"
},
{
title:
"Author Other"
,
field:
"Author.SomeotherInformation"
},
{
title:
"Modified"
,
field:
"Modified"
,
template:
'#= kendo.toString(Modified, "dd/MM/yyyy") #'
},
{
title:
"Modified orig"
,
field:
"Modified"
}
],
dataSource: {
schema: {
model: {
id:
"ID"
,
fields: {
ID: {
type:
"number"
},
Modified: {
type:
"date"
},
Author: [{
Title: {
type:
"string"
},
SomeotherInformation: {
type:
"string"
}
}],
MyNewColumn: {
type:
"date"
}
}
}
},
transport: {
read:
function
(options) {
$pnp.sp.web.lists.getByTitle(
"MyList"
).items
.select(
"Id,Author/Title,Modified"
)
.expand(
"Author"
)
.get()
.then(
function
(items) {
console.log(
"MyList results"
, items);
options.success(items);
})
//then function
.
catch
(
function
(e) {
console.log(e);
options.error(e);
})
//catch function
}
//read function
}
//transport
}
//datasource
});
//kendoGrid
I am glad to hear that you are moving forward. I had a look at the provided screenshots but I cannot see a SomeotherInformation field at all. Perhaps you intended to attach a different screenshot?
However, I would like to use this opportunity to advise you regarding the schema model definition. The schema enables the Kendo UI Data Source to parse the data that it receives. In your case, instead of binding the Kendo UI Grid to nested fields, you can use the Model:
https://docs.telerik.com/kendo-ui/api/javascript/data/model#methods-Model.define
Also, instead of using a client template, you can take advantage of columns format for the Modified column:
https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/columns.format
var
grid = $(
"#kendoGrid1"
).kendoGrid({
height: 200,
columns: [{
field:
"Title"
},{
title:
"Author Other"
,
field:
"Other"
},{
field:
"Modified"
,
format:
"{0:dd/MM/yyyy}"
},{
title:
"Modified orig"
,
field:
"Modified"
}],
dataSource: {
schema: {
model: {
id:
"ID"
,
fields: {
ID: { type:
"number"
},
Modified: { type:
"date"
},
Title: { from
"Author.Title"
},
Other : { from
"Author.SomeotherInformation"
},
MyNewColumn: { type:
"date"
}
}
}
}
// other configurations
});
We have an article which shows how to use nested properties that you may find useful:
https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/binding/use-nested-model-properties
If you need more help, Could you copy and paste the response in the thread? An easy way to do that could be to stringify it when you log it in the console, so I can test it in a runnable example:
read:
function
(options) {
$pnp.sp.web.lists.getByTitle(
"MyList"
).items
.select(
"Id,Author/Title,Modified"
)
.expand(
"Author"
)
.get()
.then(
function
(items) {
console.log(kendo.stringify(items));
options.success(items);
})
Look forward to hearing back from you.
Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Hello Lutz,
We have a similar requirement where we have to do CRUD operation of SharePoint list with fields including people picker, lookup, choice etc.. using kendo grid. Please help me with code if you have achieved this already
We have an example with SharePoint that you can have a look at here:
https://github.com/telerik/kendo-ui-sharepoint-2013-demo
Let me know in case you need further assistance.
Kind Regards,
Alex Hajigeorgieva
Progress Telerik

Here is a CRUD solution of Kendo Grid on SharePoint 2013 on premises developed by Dennis Kim.
<body>
<div>
<div id="gridSPDataUpdate"></div>
<script>
$(document).ready(function () {
$("#gridSPDataUpdate").kendoGrid({
dataSource: {
type: "json",
transport: {
create: {
data: {
'__metadata': { 'type': 'SP.Data.KendoUITestListItem' }
},
url: function (data) {
console.log(kendo.stringify(data));
return _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('KendoUITest')/items"
},
type: "POST",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
complete: function (jqXHR, textStatus) { alert("New Item Created!"); }
},
read: {
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('KendoUITest')/items",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json; odata=verbose")
}
},
update: {
url: function (data) {
return _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('KendoUITest')/items(" + data.ID + ")";
},
type: "POST",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "MERGE",
"If-Match": "*"
},
complete: function (jqXHR, textStatus) { alert("Update Success"); }
},
destroy: {
url: function (data) {
return _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('KendoUITest')/items(" + data.ID + ")";
},
type: "POST",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
//"accept": "application/json;odata=verbose",
//"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-Http-Method": "DELETE",
"If-Match": "*"
},
complete: function (jqXHR, textStatus) { alert("List Items Destroyed"); }
},
parameterMap: function (data, type) {
if (type == "update") {
for (var property in data) {
if (
property != "__metadata" &&
property != "ID" &&
property != "Title" &&
property != "First_x0020_Name" &&
property != "Organization" &&
property != "Phone_x0020_Number"
)
delete data[property];
}
}
return kendo.stringify(data);
}
},
schema: {
data: function (data) {
return data.d && data.d.results ? data.d.results : [data.d];
},
model: {
id: "ID",
fields: {
ID: {type: "number", editable: false, nullable: false },
Title: {type: "string", editable: true, nullable: false },
First_x0020_Name: { type: "string", editable: true, nullable: false },
Organization: { type: "string", editable: true, nullable: false },
Phone_x0020_Number: { type: "string", editable: true, nullable: false },
}
},
total: function (result) {
var data = this.data(result);
return data ? data.length : 0;
}
},
pageSize: 20
},
persistSelection: true,
height: 550,
editable: true,
groupable: true,
sortable: true,
batch: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
toolbar: ["create", "save", "cancel"],
columns: [{
field: "Title",
title: "Last Name",
}, {
field: "First_x0020_Name",
title: "First Name",
}, {
field: "Organization",
title: "Organization",
}, {
field: "Phone_x0020_Number",
title: "Phone Number",
}, {
command: ["destroy"],
width: 125
}]
});
});
</script>
</div>
</body>
Thank you for sharing with the Kendo UI community.
Kind Regards,
Alex Hajigeorgieva
Progress Telerik