Kendo UI ListView that consumes object with array - kendo-ui

How can I get my ListView to loop through object property timetableRecords. I'm googling around but can't find way to do it.
Example of data (swagger response model schema):
{
"from": {
"name": "string"
},
"to": {
"name": "string"
},
"price": 0,
"date": "2016-07-25T11:52:52.674Z",
"timetableRecords": [
{
"departure": "2016-07-25T11:52:52.675Z",
"arrival": "2016-07-25T11:52:52.675Z"
}
],
"fetchedOn": "2016-07-25T11:52:52.675Z"
}
HTML:
<div id="timetableRecords"></div>
<script type="text/x-kendo-template" id="template">
<div class="timetable-record">
<p>#:departure#</p>
<p>#:arrival#</p>
</div>
</script>
JavaScript:
$('#timetableRecords').kendoListView({
template: kendo.template($("#template").html()),
dataSource: {
transport: {
read: {
type: 'GET',
url: 'api/timetable?from=station_name1&to=station_name2',
dataType: 'json'
}
}
}
});

So its been awhile since you posted this, but I have a solution for you (doubtful you will still need it).
The schema.parse() event can help you:
Executed before the server response is used. Use it to preprocess or parse the server response.
Here is your updated Datasource is below:
dataSource: {
transport: {
read: {
type: 'GET',
url: 'api/timetable?from=station_name1&to=station_name2',
dataType: 'json'
}
},
schema:
parse: fucntion(e) {
return e.timetableRecords
}
}
This way your DataSource is processing a list of 'timetableRecords', and your template would be valid.
Good luck,
Grant

Related

How to parse my JSON data to String in KENDO GRID?

how can i format this object Object to its actual values ?
I want this json object to display its actual values in a specific kendo grid column .
Can someone please help me and teach me how to do it ?
This is the image of the kendo grid with the result ,
While here is the code that I am using in my view .
Can please someone help .
contact : new kendo.data.DataSource({
transport:{
read:{
type: "GET",
url:"reservation/list",
dataType:"json",
contentType: "application/json; chartset=utf-8"
},
update: {
url: "contacts/update",
dataType: "json",
type: "POST"
},
destroy: {
url: "contacts/destroy",
dataType: "json",
type:"POST"
},
create: {
url: "contacts/store",
dataType: "json",
type:"POST"
}
},
schema:{
model:{
id:"id",
fields:{
Purpose:
{
type:"string",
validation:{required:true}
},
RoomID:
{
from: "RoomID.room_name",
type: "string"
},
Equipments:
{
from: "Equipments",
type: "string"
},
start:
{
type:"date",
validation:{required:true}
},
end:
{
type:"date",
validation:{required:true}
},
}
}
},
pageSize:10
}),
init : function(e){
$("#grid").kendoGrid({
dataSource: this.contact,
selectable: true,
height:600,
editable: "popup",
filterable: true,
sortable: {
mode: "multiple",
allowUnsort: true,
showIndexes: true
},
toolbar: ["search"],
columns: [
{
field: "Purpose",
title:"Purpose"
},
{
field: "RoomID",
title:"Room",
},
{
field: "Equipments",
title:"Equipments",
},
{
field: "start",
title:"Start",
//template: '#= kendo.toString(kendo.parseDate(start), "MM/dd/yyyy HH:mm:ss")#'
format: "{0:MMM dd,yyyy hh:mm tt}",
parseFormats: ["yyyy-MM-dd'T'HH:mm.zz"]
},
{
field: "end",
title:"End",
//template: '#= kendo.toString(kendo.parseDate(end), "MM/dd/yyyy HH:mm:ss")#'
format: "{0:MMM dd,yyyy hh:mm tt}",
parseFormats: ["yyyy-MM-dd'T'HH:mm.zz"]
},
{
command: ["edit", "destroy"],
title: " ",
width: "250px"
}
],
pageable:{
pageSize:10,
refresh:true,
buttonCount:5,
messages:{
display:"{0}-{1}of{2}"
}
}
});
},
});
kendo.bind($("#whole"),model);
model.init();
Hopefully this will help you out with templating out the results.
https://dojo.telerik.com/ICOceLUj
In the example above I have created a custom column that takes the incoming row object and then parsed the name of the item and the category object into a single template.
To achieve this I have added the template property and used a function with an external template script to handle the manipulation. I personally find this easier to manage than trying to inline a complex client template (especially if you have logic involved)
So this is how we set it up initially:
{ title: "custom template", template:"#=customTemplate(data)#" }
obviously you will change it to the property you need to look at in your model.
then the function is a couple of lines of code:
function customTemplate(data){
var template = kendo.template($('#customTemplate').html());
var result = template(data);
return result;
}
so this takes the customTemplate template i have created for this and renders it as html and then it will apply the data where appropriate. The template looks like this:
<script id="customTemplate" type="text/x-kendo-template">
<div>
<h5> #:data.ProductName#</h5>
<h4>#: JSON.stringify(data.Category, null, 4) #</h4>
</div>
</script>
You can then customize this template to how you need it to look for your specific needs. You can then either create a source template for the items and then map the values back as single string or have the logic for this in the template. Which ever is most sensible in your case.
For more info on templating please look at this link:
https://docs.telerik.com/kendo-ui/framework/templates/overview
You can use kendo.stringify in your column template.
Example:
kendo.stringify(YourProperty)

Kendo Grid renders properly but does not display json data

I have been having a tough time with grids lately, mostly getting them to display properly formatted JSON data that is being fetched from a webservice (which has been checked in VS2013, and JSONLint), if a second set of eyes could please have a look at my solution and tell me whats lacking? I am going bananas!
function SetTelerikGrid() {
// prepare the data object and consume data from web service,...
$.ajax({
type: "GET",
async: false,
url: "http://localhost:38312/SDMSService.svc/GetProductPositionsByLocation/0544",
datatype: "json",
success: function (ProductData, textStatus, jqXHR) {
// populate kendo location grid by data from successful ajax call,...
$("#LocationProductsGrid").kendoGrid({
dataSource: {
data: ProductData, // solution here was: **JSON.parse(LocationData)**
schema: {
model: {
fields: {
Date: { type: "string" },
ProductCode: { type: "string" },
StoreNum: { type: "string" },
ProductQty: { type: "int" }
}
}
},
pageSize: 20
},
height: 550,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
{ field: "Date", title: "Date", width: "130px" },
{ field: "ProductCode", title: "Product Code", width: "130px" },
{ field: "StoreNum", title: "Store Number", width: "130px" },
{ field: "ProductQty", title: "Product Qty", width: "130px" }
]
});
}
});
}
There is a breaking change in ASP.NET Core, related to how the JSON serializer
works
You can probably mitigate this by adding a json option like this:
1:
change
services.AddMvc();
to
services
.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
OR
2:
public IActionResult Read()
{
// Override serializer settings per-action
return Json(
MyModel,
new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }
);
}
refrences :
http://www.telerik.com/forums/using-2016-2-630-preview---data-not-displayed#qlHR6zhqhkqLZWuHfdUDpA
https://github.com/telerik/kendo-ui-core/issues/1856#issuecomment-229874309
https://github.com/telerik/kendo-ui-core/issues/1856#issuecomment-230450923
Finally figured it out, the 'ProductData' field - although in perfect JSON format - still required to be parsed as JSON in the datasource configuration, like so,...
Data: JSON.parse(ProductData)

DataSource transport.destroy called +1 times for each successive delete (recalled for previously deleted items)

I have a DataSource in my code that support destroy. In order to delete object from the it, i directly call remove, i.e.
myDataSource.remove(discardedData);
I get a behavior similar to this. However, unlike the linked thread, my destroy is not set to a function, so the solution does not help me.
My DataSource (i included all of it in case some of my configuration is to blame):
var QueueMessages = {
type: "aspnetmvc-ajax",
transport: {
read: {
url: BASE_URL + "api/QueueMessages/GetMessagesHeaders",
dataType: "json",
type: "GET",
beforeSend: function (req) {
req.setRequestHeader('Authorization', authService.getAuth());
}
},
destroy: {
url: BASE_URL + "api/QueueMessages/deleteMessage",
dataType: "json",
type: "DELETE",
beforeSend: function (req) {
req.setRequestHeader('Authorization', authService.getAuth());
}
}
},
schema: {
model: {
id: "id",
fields: {
profileName: { type: "string" },
queueType: { type: "string" },
acceptedAt: { type: "date" },
processedAt: { type: "date" },
BodyExcerpt: { type: "string" }
}
},
total: "total",
data: "data",
},
error: function (e) {
//throw user back to login page
if (e.errorThrown === "Unauthorized")
$rootScope.$apply($location.path('/'));
},
requestStart: function () {
},
requestEnd: function () {
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
serverGrouping: true,
serverAggregates: true
};
I cant find any clues as to why this is happening.
thanks to OnaBai I found the problem.
consulting RFC 7231, i my changed the http DELETE response from 200 OK to 204 no content.

Kendo ASP.NET MVC Grid and WebAPI - Data does not show up in grid

I have an APIController with a HttpGet which returns this JSON response:
[{"Customer":"AAAA","Office":"Off1"},{"Customer":"AAAA","Office":"Off2"}]
This is hosted on a remote server.
I'm testing my local client, connecting to this server with this:
<div class="k-content">
<div id="Grid"></div>
</div>
<script type="text/javascript">
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://<remoteserver>/<apicontroller>/<actionMethod>",
dataType: "json",
data: { customerFilter: "AAAA", topFilter: "10" }
}
},
schema: {
model: {
Customer: "Customer",
Office: "Office"
}
}
});
$(document).ready(function () {
$("#Grid").kendoGrid({
dataSource: dataSource,
height: 400,
columns: [
{ field: "Customer" },
{ field: "Office" }
]
});
});
</script>
Checking in fiddler, I get the response shown above. However, the grid is empty.
If i hard code the data into the data source like below, the grid populates, so it seems as if, even though the response is received, the grid doesn't know how to parse it.
var dataSource = new kendo.data.DataSource({
data:
[{"Customer":"AAAA","Office":"Off1"},{"Customer":"AAAA","Office":"Off2"}],
schema: {
model: {
Customer: "Customer",
Office: "Office"
}
}
Anyone have some ideas what might be the problem?
Thanks.
Your configuration of the datasource is incorrect. The Kendo UI documentation can be hard to follow, but this is how you need to define a datasource:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://<remoteserver>/<apicontroller>/<actionMethod>",
dataType: "json",
data: { customerFilter: "AAAA", topFilter: "10" }
}
},
schema: {
model: {
fields: {
Customer: {},
Office: {}
}
}
}
};
No need to mention entire url. You can also just specify uri.
example:
var uri = 'api/products';
var ds = new kendo.data.DataSource({
transport: {
read: {
url:uri,
dataType: "json"
}
}
});

kendo ui how to filter dataSource requestStart

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");
}
});
}
}

Resources