Access nested property in Kendo Grid - kendo-ui

Following is the kendo grid where the nested property has to be accessed:
function detailInit(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
transport: {
read: constants.AppUrls.GetUrls().WebApi + "gprScoreprofiel/GetProfielen/" + e.data.id
},
serverPaging: false,
serverSorting: false,
serverFiltering: false,
sortable: { mode: 'single' },
pageSize: 5,
schema: {
type: "json",
data: "items",
model: {
fields: {
isBerekend: { from: "isBerekend", type: "boolean" },
GPR: { from: "gprGebouwVersieId", type: "string" },
En: { from: "en", type: "number" },
Mi: { from: "mi", type: "number" },
Gz: { from: "gz", type: "number" },
Gb: { from: "gb", type: "number" },
Tk: { from: "tk", type: "number" },
Dpg: { from: "dpg", type: "number" },
VariantNaam: { from: "variant.naam", type: "string" }
}
}
}
},
dataBound: function (e) {
},
reorderable: true,
resizable: true,
sortable: true,
columnMenu: false,
scrollable: true, //http://www.telerik.com/forums/max-height-on-grid
pageable: {
refresh: true,
pageSizes: ["All", 10, 20, 50, 100, 200],
buttonCount: 5,
messages: {
display:
"{0} - {1} van {2} adressen", //{0} is the index of the first record on the page, {1} - index of the last record on the page, {2} is the total amount of records
empty: "Geen adressen",
page: "Page",
of: "of {0}", //{0} is total amount of pages
itemsPerPage: "adressen per pagina",
first: "Ga naar de eerste pagina",
previous: "Ga naar de vorige pagihna",
next: "Ga naar de volgende pagina",
last: "Ga naar de laatste pagina",
refresh: "Herlaad"
}
},
columns:
[
{ field: "isBerekend", title: "Berekend", template: "#= isBerekend ? 'Ja' : 'Nee' #" },
{ field: "GPR", title: "GPR versie" },
{ field: "En", title: "Energie" },
{ field: "Mi", title: "Milieu" },
{ field: "Gz", title: "Gezondheid" },
{ field: "Gb", title: "Gebruik" },
{ field: "Tk", title: "Toekomst" },
{ field: "Dpg", title: "Energie en Milieu" },
{ field: "VariantNaam", title: "Variant Naam" }
]
}).data("kendoGrid");
}
On accessing the api we get the following data:
{
"resultaatgegevens": null,
"items": [
{
"isBerekend": true,
"gprGebouwBerekeningId": 37391,
"gprGebouwVersieId": 10,
"gebruikersdoelId": 1,
"gebruikersdoel": "Celfunctie",
"gebruikstypeId": 9,
"gebruikstype": "Twee onder een kap woning",
"bouwjaarKlasseId": 6,
"gemiddeld": 7.0,
"en": 8.4,
"en1": 8.9,
"en2": 6.6,
"en3": 0.0,
"mi": 6.0,
"mi1": 6.6,
"mi2": 6.2,
"mi3": 5.9,
"gz": 6.9,
"gz1": 5.9,
"gz2": 6.9,
"gz3": 7.5,
"gz4": 7.0,
"gb": 7.5,
"gb1": 6.2,
"gb2": 6.7,
"gb3": 10.0,
"gb4": 6.7,
"tk": 6.2,
"tk1": 6.3,
"tk2": 5.6,
"tk3": 6.6,
"dpg": 0.0,
"dpg1": 0.0,
"bouwjaarKlasse": null,
"gprGebouwVersie": null,
"gprScoreprofielByVastgoedItems": null,
"variant": {
"id": 10,
"naam": "VariantId10",
"omschrijving": "VariantId10",
"gprScoreprofielen": null
}
},
{
"isBerekend": false,
"gprGebouwBerekeningId": 0,
"gprGebouwVersieId": 11,
"gebruikersdoelId": 28,
"gebruikersdoel": "Woonfunctie",
"gebruikstypeId": 3,
"gebruikstype": "portiekwoning 1965 1974",
"bouwjaarKlasseId": 3,
"gemiddeld": 5.2,
"en": 5.9,
"en1": 6.0,
"en2": 5.6,
"en3": null,
"mi": 5.0,
"mi1": 5.4,
"mi2": 4.0,
"mi3": 4.8,
"gz": 4.4,
"gz1": 4.5,
"gz2": 4.2,
"gz3": 4.8,
"gz4": 4.2,
"gb": 5.1,
"gb1": 6.0,
"gb2": 6.0,
"gb3": 3.0,
"gb4": 5.4,
"tk": 5.6,
"tk1": 6.0,
"tk2": 6.0,
"tk3": 4.8,
"dpg": null,
"dpg1": null,
"bouwjaarKlasse": null,
"gprGebouwVersie": null,
"gprScoreprofielByVastgoedItems": null,
"variant": null
}
],
"page": 1,
"pageSize": 1000,
"total": 0,
"hasMore": false
}
The grid doesn't work due to variant.naam

From the docs:
A field configuration cannot contain nested fields' configurations.
So, you have two options:
Change your API to return the nested properties in the same level as the items, e.g.: variantnaam;
Or do it in the Javascript before the widget renders it in schema.parse, something like:
schema: {
data: "items",
parse: function(data) {
if (data && data.items) {
var key = "variant";
data.items.forEach((i) => {
if (i[key]) {
Object.keys(i[key]).forEach((k) => {
i[key + k] = i[key][k];
});
}
});
}
return data;
}
}
Demo

Related

Kendo Grid Server side filtering with a array type column

I have this kendo grid blinded to my web service. One of the columns has a custom filter with a kendo multiselector array so the client can choose multiple ItemTypes. The grid is displaying data correctly but my costume filters are not working for this particular column. I got this error from the service: "A binary operator with incompatible types was detected. Found operand types 'Telerik.Sitefinity.DynamicTypes.Model.ClinicFinder.Clinic.ItemType.ItemType' and 'Edm.Int32' for operator kind 'Equal'."
My grid definition
$("#grid").kendoGrid({
dataSource: {
type: "odata-v4",
transport: {
read: {
url: function () {
return "//myservice/api/clinics?$select=Id,Title,Address,ItemType,productsystems&top=20";
}
}
},
schema: {
model: {
fields: {
Title: { type: "string" },
CountryCode: { type: "string" },
Street: { type: "string" },
City: { type: "string" },
Zip: { type: "string" },
ItemType: { type: "" }
}
}
},
serverPaging: true,
serverFiltering: true,
serverSorting: false,
pageSize: 20
},
pageable: true,
filterable: {
mode: "row",
extra: false,
showOperators: false,
operators: {
string: {
contains: "contains"
}
}
},
sortable: false,
columns: [
{ field: "Title", title: "Clinic" },
{ field: "CountryCode", title: "Country" },
{ field: "Street", title: "Address" },
{ field: "City", title: "City" },
{ field: "Zip", title: "Zip", filterable: false },
{ field: "ItemType", title: "Clinic Type", filterable: { multi: true } }
],
rowTemplate: kendo.template($("#template").html())
});
My Filter function
function filterByclinicCategory() {
var filter = { logic: "or", filters: [] };
var grid = $('#grid').data('kendoGrid');
var filterValue = $("#clinicTypeFilter").data("kendoMultiSelect").value();
var clinicCode = [];
if (filterValue.length > 0) {
$.each(filterValue, function (i, v) {
clinicCode.push(convertClinicTypesInCodes(v));
filter.filters.push({
field: "ItemType", operator: "eq", value: clinicCode, logic: "or"
});
grid.dataSource.filter(filter);
});
} else {
$("#grid").data("kendoGrid").dataSource.filter({});
}
}
ItemType is the column I canĀ“t filter.
My webservice data
{
"#odata.context": "https://sf-admin-local.medel.com/api/wstest/$metadata#clinics(*)",
"value": [
{
"Id": "896aa08b-2f17-64e6-80bd-ff09000c6e28",
"LastModified": "2019-05-13T09:28:04Z",
"PublicationDate": "2018-06-19T14:19:13Z",
"DateCreated": "2018-06-19T14:19:13Z",
"UrlName": "??",
"Email": "",
"URL": "",
"Telephone": "",
"Title": "????????",
"officeregions": [],
"salespartnerregions": [],
"productsystems": [
"b8ec2a8b-2f17-64e6-80bd-ff09000c6e28",
"1878cb61-ac79-69d9-867b-ff01007297b6",
"1b78cb61-ac79-69d9-867b-ff01007297b6",
"36d8938b-2f17-64e6-80bd-ff09000c6e28"
],
"Area": "",
"Order": 0,
"Tags": [],
"AdditionalInformation": "",
"ImportID": 1,
"Featured": false,
"ItemType": "2",
"Address": {
"Id": "d76aa08b-2f17-64e6-80bd-ff09000c6e28",
"CountryCode": "AT",
"StateCode": "",
"City": "????",
"Zip": "6800",
"Street": "Carinagasse ?????",
"Latitude": 47.2311043,
"Longitude": 9.580079999999953,
"MapZoomLevel": 8
}
}
]
}
I manage to fix it using parameterMap https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/transport.parametermap.
I add a parameterMap: functiondata, type) function, with that I was able to intercept and change the call made by the filters.
parameterMap: function (data, type) {
var c = kendo.data.transports["odata-v4"].parameterMap(data, type);
if (c.$filter) {
//my transformation
c = myTransformation;
return c;
} else{
return c; //not apply transformation loading the data
}
}

How to add more on chart by select more items on multi dropdownlist

I have a multiselect dropDownList and a chart,i want my chart to by dynamic to plot more based on my multiselect dropdownlist,but i have no idea, I would appreciate if you give me a hint by a demo or an example.because in the following code,i have a chart which works only based normal dropdownlist not the multiplechioce,
Here is Multiselect:
$('#multiselect').kendoMultiSelect({
dataTextField: "Text",
dataValueField: "Text",
valuePrimitive: true,
dataSource: result.list_of_parks,
})
here is the chart:
function createChart(data, data_wind) {
$("#topMonth").kendoChart({
series: [{
data: data,
type: "column",
axis: "l100km",
field: "productionvalue",
categoryField: "name",
color: "#228B22"
},
{
axis: "ava",
data: data_wind,
type: "line",
field: "windvalue",
categoryField: "name",
color: "#007eff",
},
],
valueAxes: [
{
name: "l100km",
title: { text: "Production (MW/H)" },
// min: 0,
// max: 2000000,
// majorUnit: 200000,
majorGridLines: {
visible: false
},
minorGridLines: {
visible: false
},
},
{
name: "ava",
title: { text: "Averge Wind Speed(KM/H)" },
min: 0,
// max: 20,
majorUnit: 1,
majorGridLines: {
visible: false
},
minorGridLines: {
visible: false
},
}
],
categoryAxis: {
majorGridLines: {
visible: false
}
,
labels: {
padding: {
left: -20,
buttom: 0
},
rotation: 340
},
axisCrossingValues: [0, 20],
},
tooltip: {
visible: true,
// majorUnit:10,
template: " #= value #"
},
});
$(window).on("resize", function () {
kendo.resize($(".chart-wrapper"));
});
}
}
});
});

kendo grid server re filtering the data source

$(document).ready(function () {
var agenciesData = new kendo.DataToken.DataSource({
type: 'webapi',
transport: {
read: { url: "/api/Agencies/", dataType: "json", data: { activity: getActivity() } },
create: { url: "/api/Agencies", type: "POST", dataType: "json" },
destroy: { url: "/api/Agencies/{0}", type: "DELETE" },
update: { url: "/api/Agencies/{0}", type: "PUT" },
idField: "ID"
},
filter: [{ field: "Activity", operator: "eq", value: getActivity() }],
pageSize: 15,
page: 1,
total: 0,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
schema: {
data: "Data",
total: "Total",
model: {
id: "ID",
fields: {
ID: { editable: false, type: "number" },
AgencyName: { type: "string" },
AgentName: { type: "string" },
Address: { type: "string" },
City: { type: "string" },
Tel1: { type: "string" },
Tel2: { type: "string" },
Pele: { type: "string" },
Activity: { type: "number" },
ToDate: { type: "date" }
}
}
}
});
$("#agenciesGrid").kendoGrid({
dataSource: agenciesData,
toolbar: [{ text: "valid", className: "validAgents" }, { text: "not valid", className: "notValid" }, { text: "all", className: "allAgents" }, { text: "potential", className: "potetial" }],
editable: false,
navigatable: true,
sortable: true,
autoBind: false,
height: 430,
pageable: { refresh: true },
columns: [
{ field: "ID", hidden: true },
{ field: "AgencyName", title: "agency", width: 150, filterable: { cell: { operator: "contains" } } },
{ field: "AgentName", title: "agent", width: 150, filterable: { cell: { operator: "contains" } } },
{ field: "Address", title: "address", width: 200, template: "#= Address + ' ' + City #", filterable: false },
{ field: "Tel1", title: "phones", width: 300, template: "#= Tel1 + ' : ' + Tel2 + ' : ' + Pele #", filterable: false },
{ field: "Activity", title: "active", width: "90px" },
{ field: "ToDate", title: "end Contract", type: "date", width: 90, format: "{0:dd/MM/yyyy}", parseFormats: ["yyyy-MM-ddThh:mm:ss"] }
]
});
$(".validAgents").click(function () { //valid
$("#myActivity").val("1");
$('#agenciesGrid').data().kendoGrid.dataSource.read({ activity: "1" });
});
$(".notValid").click(function () {//notValid
$("#myActivity").val("2");
$('#agenciesGrid').data().kendoGrid.dataSource.read({ activity: "2" });
});
$(".potetial").click(function () {//potetial
$("#myActivity").val("3");
$('#agenciesGrid').data().kendoGrid.dataSource.read({ activity: "3" });
});
});
function getActivity(){
var myActivity = $("#myActivity").val();
return myActivity;
}
When I use kendo grid already filtered by parameter like : $('#someGrid').data().kendoGrid.dataSource.read({ activity: value });
i see the get: https://localhost:44305/api/Agencies/?sort=&page=1&pageSize=15&group=&filter=&activity=1
The grid is filter as expected but, when I want to do paging, sorting, refresh - I get the whole data ignoring the filter that i made.
and I see the get: https://localhost:44305/api/Agencies/?sort=&page=1&pageSize=15&group=&filter=
How can I save my filter state to do paging and sorting on the data came from the server side ?
even when i used differen approach like "scrollable: { virtual: true }" and when i scroll down - every request is without the filtering...
Thanks
Did you try
var agenciesData = new kendo.DataToken.DataSource({
filter : function () {
return object;
}
});
I mean try using filter as a function and you can do your logic inside the function depending on the situation.

kendo grid how to set the schema.model with a foreign key field

need help about adding a new recort in a kendo grid.
I have a grid with a foreign key field. The grid is populated by a json data with subobject, returned from a webmethod. it looks like this:
[
{
"classe_iva": {
"id_classe_iva": 5,
"desc_classe_iva": "Esente",
"note_classe_iva": null
},
"id_iva": 37,
"desc_iva": "bbb",
"codice_iva": "bbb",
"imposta": 2,
"indetr": 2,
"id_classe_iva": 5,
"note": "dddddfsf",
"predefinito": false,
"id_company": 4
},
{
"classe_iva": {
"id_classe_iva": 6,
"desc_classe_iva": "Escluso",
"note_classe_iva": null
},
"id_iva": 52,
"desc_iva": "o",
"codice_iva": "jj",
"imposta": 1,
"indetr": 1,
"id_classe_iva": 6,
"note": "l",
"predefinito": false,
"id_company": 4
}
]
and this is the schema.model used in the kendo datasource:
model = {
id: "id_iva",
fields: {
id_iva: { type: "string", editable: false },
desc_iva: { type: "string" },
codice_iva: { type: "string" },
imposta: { type: "number" },
indetr: { type: "number" },
id_classe_iva: {type: "string"},
note: { type: "string" },
predefinito: { type: "boolean" },
id_company: { type: "number" }
}
}
.. and below is shown the grid columns format:
toolbar = [{
name: "create",
text: "Aggiungi nuova aliquota IVA"
}];
columns = [
{ field: "desc_iva", title: "Descrizione", width: 45 },
{ field: "codice_iva", title: "Codice", width: 45 },
{ field: "imposta", title: "Imposta", width: 45 },
{ field: "indetr", title: "Indetr", width: 45 },
{ field: "classe_iva.desc_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= classe_iva ? classe_iva.desc_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
{ field: "note", title: "Note", width: 45 },
{
command: [{
name: "destroy",
text: "Elimina",
confirmation: "Sei sicuro di voler eliminare questa voce?"
} ,
{
name: "edit",
text: {
edit: "Modifica",
update: "Aggiorna",
cancel: "Cancella"
}
}
]
}
];
Theese settings works fine when i edit a row, and the grid shows the right content into the combobox field.
The problem is when i click on the "add new record" button, because when it tries to add a new row, it doesn't find the subobjects field "classe_iva".
if i change the column.field into this
{ field: "id_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= id_classe_iva ? id_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
{ field: "note", title: "Note", width: 45 }
the add button works fine, but when the grid is loaded, the column id_classe_iva doesn't shows me the classe_iva.desc_classe_iva field...
how can i fix the issue??^?
thanks in advance.
to fix this issue, i used a workaround:
the error was thrown because, in the declaration of the field.template there where a not declared variable (classe_iva):
{ field: "id_classe_iva", title: "Classe IVA", width: 200, editor: categoryDropDownEditor, template: "#= classe_iva ? classe_iva.desc_classe_iva : 1 #", defaultValue: { id_classe_iva: 1, desc_classe_iva: "Acq. Intra-UE" } },
then, i declared a global variable
var classe_iva;
in this way, when i add a new record, the code doesn't throw any errors, and by the ternary if, the default value is set.
hope it will help someone.

jqGrid is empty with JSON call

My jqGrid is coming empty with JSON call. Though it is working with datatype='jsonstring' but not with json type. here is my JSON
{
"d": {
"total": 6,
"page": 1,
"records": 6,
"rows": [
{
"id": 1,
"Name": "James",
"EMPID": "0000000056",
"EMPDATE": "",
"JOBTYPE": "REQ",
"DEPTID": "FIN",
"STATUS": "P1"
},
{
"id": 2,
"Name": "James",
"EMPID": "R2",
"EMPDATE": "",
"JOBTYPE": "REQ",
"DEPTID": "FIN",
"STATUS": "P1"
},
{
"id": 3,
"Name": "James",
"EMPID": "V2",
"EMPDATE": "",
"JOBTYPE": "VOU",
"DEPTID": "FIN",
"STATUS": ""
},
{
"id": 4,
"Name": "James",
"EMPID": "V1",
"EMPDATE": "",
"JOBTYPE": "VOU",
"DEPTID": "FIN",
"STATUS": ""
},
{
"id": 5,
"Name": "James",
"EMPID": "009017",
"EMPDATE": "",
"JOBTYPE": "PY",
"DEPTID": "",
"STATUS": "V2"
},
{
"id": 6,
"Name": "James",
"EMPID": "009018",
"EMPDATE": "",
"JOBTYPE": "PY",
"DEPTID": "",
"STATUS": "V1"
}
]
}
}
and my jqGrid call from javascript is
function getgrid()
{
$("#list").jqGrid({
url:'http://10.240.26.41/GetGridFields',
datatype: 'json',
mtype: 'GET',
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
//serializeGridData: function (postData) {
// return JSON.stringify(postData);
// },
jsonReader: { repeatitems: false, root: "d.rows", page: "d.page", total: "d.total", records: "d.records" },
colModel: [
{ name: 'id', key: true, width: 60, align: "center", hidden: false },
{ name: 'Name', width: 80, sortable: false, hidden: false },
{ name: 'EMPID', width: 180, sortable: false, hidden: false },
{ name: 'EMPDATE', width: 180, sortable: false, hidden: false },
{ name: 'JOBTYPE', width: 180, sortable: false, hidden: false },
{ name: 'DEPTID', width: 180, sortable: false, hidden: false },
{ name: 'STATUS', width: 180, sortable: false, hidden: false }
],
rowNum: 10,
rowList: [10, 20, 300],
pager: "#pager",
viewrecords: true,
gridview: true,
rownumbers: true,
height: 230,
caption: 'Emp Detail'
})
}
Please let me know where i am wrong here. It is working fine with jsonstring.
How you can see on the demo your jqGrid can read your JSON data. I made in the demo only minimal optimization changes which don't important for your main problem.
So I suppose, that you have either the problem with the usage of full URL (you should use '/GetGridFields' instead of 'http://10.240.26.41/GetGridFields') because you can't get Ajax call to another IP host because of the same origin policy. One other possible reason is that you have wrong 'Content-Type' or some other HTTP header. You can examine the HTTP headers with respect of Fiddler, Firebug or just with Developer Tools of IE or Chrome (see "Network" tab).
In any way I would recommend you to include loadError handler to jqGrid. See the answer for details.
I suggest you validate your json result using jslint since using jsonstring is working could be a format type problem

Resources