Kendo Grid renders properly but does not display json data - ajax

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)

Related

Kendo Grid Serverside Paging, Incorrect Parameter Map values

I'm trying to use the Dynamic Linq Helper libraries from Kendo. The parameter map function on the grid does not have the correct parameters to send to the controller.
The parameterMap options have:
{"take":10,"skip":0,"page":1,"pageSize":10}
but according to the example, it should have take, skip, sort, filter, which is not in the parameterMap function or getting passed to the server.
I'm following the example here
http://www.telerik.com/blogs/kendo-ui-open-sources-dynamic-linq-helpers
And also looked other examples, my grid is set up the same as the others.
The only difference being, this is a Web API single page app, not MVC. However, this shouldn't make a difference in what the Grid class is passing to it's parameterMap function.
What is going on here?
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "http://localhost/biahost/query/projectStatuses",
dataType: "application/json",
type: "POST",
contentType: "application/json; charset=utf-8"
//data:{}
},
parameterMap: function (options) {
debugger;
//options only contain {"take":10,"skip":0,"page":1,"pageSize":10}
return kendo.stringify(options);
}
},
schema: {
data: "Data",
total: "Total",
model: {
fields: {
NAME: { type: "string" },
CODE: { type: "string" },
STATUS: { type: "string" },
COMMENTS: { type: "string" },
INSERTS: { type: "string" },
UPDATES: { type: "string" },
TOTAL_UPDATES: { type: "string" },
LAST_ACTION_DATE: { type: "string" }
//UnitId: { type: "string" },
//UnitName: { type: "string" }
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
filterable: true,
sortable: true,
pageable: true,
columns: projectStatusColumns
});
var projectStatusColumns = [
{
field: 'NAME',
label: 'Res name',
hidden: true,
},
{
field: 'CODE',
label: 'Code'
},
{
field: 'STATUS',
label: 'Status'
},
{
field: 'COMMENTS',
label: 'Comments'
}
,
{
field: 'INSERTS',
label: 'Inserts'
}
,
{
field: 'UPDATES',
label: 'Updates'
}
,
{
field: 'TOTAL_UPDATES',
label: 'Total Updates'
}
,
{
field: 'LAST_ACTION_DATE',
label: 'Last Action Date'
}
];
had the same problem so i looked it up and here i am. You just need to return "options" which contains the parameter map as it is, if you stringify it will become a json object which cannot be defined in a url.
Hope i'm not too late!

Kendo: inner grid based on passed datafrom main grid does not update model after change

I have following init function for inner grid.
Date are fetched but after the change od some data in inner grid is not diplayed small red arrow signalizing change on the dataSource (model).
So if i processed update request no changes made in the inner grid is send back in the request (always it send old data).
How can i solve it please and what i'm doing wrong?
I tried to find some solution here and in documentation but without luck.
Thanks for any help.
function detailInit(e) {
//var dataSource = options.model.get("costCategory");
console.log(e);
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
data: e.data.milestones,
schema: {
model: {
fields: {
id: {
type: "string"
},
estimate: {
type: "number",
nullable: true,
defaultValue: null,
editable: true
},
actual: { type: "number" }
}
},
data: function(response) {
console.log(response);
return response;
},
},
pageSize: 10
},
scrollable: false,
sortable: true,
editable: "incell",
columns: [
{ field: "id", width: "70px" },
{ field: "milestoneTemplate.name", title:$translate.instant('MILESTONE_TEMPLATE_NAME'), width: "110px" },
{ field: "estimate", title:$translate.instant('ESTIMATE'), width: "110px" },
{ field: "actual", title:$translate.instant('ACTUAL') },
]
});
};

Get all updated and newly created models together in a single url in server side

I am Using Kendo grid with batch edit. I want to get all Modified and newly created models together in a single url.
Say I have created 3 new row and also updated/edited 2 existing row in grid. Data source makes a HTTP request for every CRUD operation . The changed data items are sent by default as models and hit URL as I declared in “create” and update (transport) section of transport in datasource.I am getting models those are Modified (updated) in URL declared for ‘update’ in server side. And also find models those are newly created in URL declared for ‘create’….But I want to get all Modified and newly created models together in a single url.Is it possible to get all of the (both all modified and newly created) in a single URL?
Here is my Code for better understand.
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "LoadPerMeterCostsGridData",
type: "POST",
contentType: "application/json",
dataType: "json"
},
update: {
url: "UpdatePerMeterCostsData",
contentType: "application/json",
type: "POST",
dataType: "json"
},
create: {
url: "CreatePerMeterCostsData",
contentType: "application/json",
type: "POST",
dataType: "json",
},
parameterMap: function (data, operation) {
if (operation != "read") {
return kendo.stringify(data.models);
}
}
},
serverPaging: false,
pageSize: 10,
batch: true,
schema: {
model: {
id: "PerMeterCostID",
fields: {
PerMeterCostID: { editable: false },
DrillBitSizeID: { editable: true },
Form: { editable: true },
To: { editable: true },
PerMeterCost: { editable: true },
ContractID: { editable: false }
}
},
errors: "Errors"
},
error: function (e) {
alert(e.errors + "grid");
}
},
editable: true,
pageable: {
refresh: true,
pageSizes: true
},
toolbar: ["create",
"save",
"cancel"
],
sortable: true,
autoBind: false,
columns:
[
{ field: "PerMeterCostID", width: 50, hidden: true, title: "ID" },
{ field: "DrillBitSizeID", width: 100, hidden: true, title: "Consumable" },
{ field: "Form", width: 100, title: " Form " },
{ field: "To", width: 50, title: "To" },
{ field: "PerMeterCost", width: 100, title: "Per Meter Cost" },
{ field: "ContractID", width: 100, hidden: true, title: "ContractID" },
{ command: ["destroy"], title: "Action", width: "175px" }
]
});
$("#grid ").data("kendoGrid").dataSource.read();
You can set each CRUD action to use the same url, but using the same url: property for both Create and Update. However you will still minimally get TWO requests (albeit to the same url)
update: {
url: "UpdateOrCreateAction",
},
create: {
url: "UpdateOrCreateAction",
},
this is because internally the dataSource pushes all "new" items as defined by "items an Id Field set to the default value for the field" in an array, and all items with dirty set to true into a different array. Kendo then sends both arrays back to the server according to the url for the action. (something like this i'd imagine)
if ( model.isNew())
createdPile.push(model)
else if ( model.dirty === true)
updatedPile.push(model)
//send both piles to the server
The "easiest" way to avoid this is to make sure your new objects explicitly set their id fields to something other then the default, and set the models dirty prob to true.
you could do this by using the edit event to override the actions
grid.bind('edit', function(e){
if ( e.model.isNew() ) {
e.model.id = -1; //
e.dirty = true;
console.log(e.model.isNew()) // should be false
}
})
this is probably an extreme amount of overkill to avoid one additional request, and prone to error. I would advise that you use the same url for both actions, and just accept that you will get the created items in one batch, and the updated in another.

Kendo Grid Will not populate with server side data

I cannot get Kendo Grid to populate from server side data.
I have a grid builder function as as follows:
var build = function (carrier, date) {
var urlBase = 'my base url';
var datasource = new kendo.data.DataSource({
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
schema: {
model: {
id: 'Id',
fields: {
StatementDate: { type: "string", editable: false },
CobDate: { type: "string", editable: false },
//lots more fields
Status: { type: "string", editable: false },
Matched: { type: "boolean", editable: true }
}
}
},
transport: {
read: function (options) {
var address = urlBase + '/' + carrier + '/' + date;
$.ajax({
url: address,
type: "POST",
data: JSON.stringify(options.data),
contentType: "application/json",
success: function (result) {
options.success(result);
},
error: function (result) {
options.error(result);
}
});
},
//update function omitted
parameterMap: function (data, operation) {
if (operation == "read") {
return JSON.stringify(data)
}
},
change: function (e) {
var data = this.data();
console.log(data.length); // displays "77"
}
}
});
return datasource;
};
return {
build: build
}
Grid Definition
elem.kendoGrid({
columns: [
{ field: "StatementDate", title: "State Date", width: 125 },
{ field: "CobDate", title: "COB Date", width: 100 },
//lots more fields
{ command: ["edit"], title: " ", width: "85px"}],
resizable: true,
sortable: true,
editable: "inline",
columnMenu: true,
filterable: true,
reorderable: true,
pageable: true,
selectable: "multiple",
change: this.onSelectedRecordChanged,
toolbar: kendo.template($('#' + templateName).html()),
scrollable: {
virtual: true
},
height: 800
});
I trigger the update via a button click. When I look at the response I see the data. Looks good but the grid will not show the data. It has previously worked fine when data was completely client side.
If I break point on the AJAX call back. I see the correct results.
The grid is bound with data bind. The datasource is a property on a viewmodel.
<div id="grid" data-bind="source: dataSource"></div>
At the start of the app. I create view model
var viewModel= kendo.observable(new GridViewModel(...
and bind
kendo.bind($('#grid'), viewModel);
If I look at the datasource attached to the grid, I see data for the page as expected
This has previously worked fine when data was client side.
I have tried using read() on datasource, and refresh() method on grid. Neither seems to work.
Example response content from server
{"Data":[{"Id": //lots more fields, 20 records],"Total":90375,"AggregateResults":null,"Errors":null}
Any help very much appreciated.
I found the cause in datasource schema missing
{ data: 'Data', total: 'Total' }

Kendo UI DataSource not triggering transport.destroy

I am using Kendo UI with ASP.NET Web API. There is a ProjectsController that has all the necessary methods.
My issue is that when I click on Delete button, Kendo UI grid will raise remove() event, but DataSource never invokes transport.destroy. Rather, it seems that tansport.create is being invoked. In transport.parameterMap I can see that the operation is create instead of destroy.
Here is a sample JavaScript code:
$(document).ready(function () {
var apiUrl = '/api/projects/';
var dataType = 'json';
var dataSource = new kendo.data.DataSource({
batch: true,
autoSync: false,
transport: {
read: {
url: apiUrl,
dataType: dataType,
type: "GET"
},
update: {
url: apiUrl,
dataType: dataType,
type: "PUT"
},
destroy: {
url: apiUrl,
type: "DELETE"
},
create: {
url: apiUrl,
contentType: "application/json;charset=utf-8",
dataType: dataType,
type: "POST"
},
parameterMap: function (data, operation) {
console.log("Operation: " + operation);
if (operation === "create" && data.models) {
for (var i in data.models) {
var model = data.models[i];
if (model.ProjectId === 0) {
return kendo.stringify(model);
}
}
} else if (operation === "destroy") {
console.log("Data.Models: " + data.models);
console.log("Data.id: " + data.ProjectId);
return { id: data.ProjectId };
}
return data;
}
},
schema: {
id: "ProjectId",
model: {
fields: {
ProjectId: { type: "number", editable: false, nullable: false, defaultValue: 0 },
ProjectName: { type: "string", validation: { required: true } },
Status: { type: "string", validation: { required: true } },
IsActive: { type: "boolean" }
}
}
},
pageSize: 10,
serverPaging: false,
serverFiltering: false,
serverSorting: false
});
$("#projectsGrid").kendoGrid({
dataSource: dataSource,
groupable: false,
sortable: true,
pageable: {
refresh: true,
pageSizes: true
},
pageSize: 10,
toolbar: ["create"],
editable: "popup",
columns: [
{ field: "ProjectId", width: 30, title: "ID" },
{ field: "ProjectName", width: 180, title: "Project" },
{ field: "Status", width: 90, title: "Status" },
{ field: "IsActive", width: 40, title: "Is Active", type: "boolean", template: '<input type="checkbox" #if (IsActive) {# checked="checked" #}# disabled="disabled" />' },
{ command: ["edit", "destroy"], title: "&nbsp", width: "80px" }
],
remove: function (e) {
console.log("Delete button clicked.");
console.log("Project ID: " + e.model.ProjectId);
//dataSource.remove(e.model);
//dataSource.sync();
}
});
});
Web API works fine when requests are issued via Fiddler, but Kendo UI Grid shows:
POST http://localhost:port/api/Projects
when it should be DELETE.
Thanks everyone in advance!
On your datasource, you have the batch flag set to true, this means the datasource will make the call only after you tell it to, e.g calling sync().
http://docs.kendoui.com/api/framework/datasource#configuration-batch
As well as
Make sure you have defined Id in the model, as OnaBai explained here Why does the KendoUI Grid Transport Create event gets raised multiple times, and even when the action is Update? , your id is outside the model, should be in :
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
}
}
if someone has defined the id in model as answered in above ,but dataSource not triggering transport.destroy yet ,below configuration could be helpful:
editable: {
..
mode: "inline", //or "popup
...
}
//or
editable: "inline" //or "popup"
http://www.telerik.com/forums/transport-destroy-of-grid-editor-is-not-working

Resources