Kendo Grid: populating with data from ajax - javascript

I'm trying to populate a kendo grid with data retrieved via ajax. Here is the ajax:
var model = #Html.Raw(Json.Serialize(Model));
$(document).ready(function () {
$.ajax({
url: "/Utilities/Report/Run",
data: JSON.stringify(model),
contentType: "application/json",
type: "POST",
success: function(result) {
var ds = new kendo.data.DataSource({
data: result
});
alert(result);
$("#grid").data("kendoGrid").setDataSource(ds);
},
error: function(result) {
options.error(result);
}
});
$("#grid").kendoGrid({
toolbar: ["excel", "pdf"],
excel: {
fileName: "test"
},
pdf: {
fileName: "test"
},
});
});
At the alert(result) this is what the data looks like:
[
{"TEST":"one"},
{"TEST":"two"},
{"TEST":"three"}
]
The ajax call appears to be working and the data looks good to me, but the kendo grid is not updating, it remains blank. I also do not get any error. I've tried placing the kendoGrid inside the ajax success function with the same result. I've tried using transport and read in the DataSource to retrieve the data but that kept giving me an error: n.slice is not a function. However, others seemed to think that was because there was no schema defined. Due to the kind of data I am retrieving, I cannot define this. The data retrieved from the server could have any column/field names, and any number of columns. It is not complex JSON however.
How do I get my grid to populate with this data?

I have created a new Datasource and mapped it to the existing one outside the success method.
Can you try this one below :
var newDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Utilities/Report/Run",
dataType: "json",
data: JSON.stringify(model),
error: function (result) {
options.error(result);
}
}
}
});
var d1 = $("#grid").data("kendoGrid");
d1.dataSource.data([]);
d1.setDataSource(newDataSource );
make changes as per your necessity if I have missed any . Kendo data binding is always confusing :D

Kendo DataSource is very powerful. Ideally, you do not need to make a manual Ajax call. Instead, DataSource can Ajax request data from URL by itself, if Grid needs data.
https://jsfiddle.net/6gxqsrzu/
$(function() {
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: {
type: "number"
},
Freight: {
type: "number"
},
ShipName: {
type: "string"
},
OrderDate: {
type: "date"
},
ShipCity: {
type: "string"
}
}
}
},
serverPaging: true,
pageSize: 5,
serverSorting: true,
sort: {
field: 'OrderDate',
dir: 'asc'
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
pageable: true,
columns: [{
field: "OrderID",
filterable: false
},
"Freight", {
field: "OrderDate",
title: "Order Date",
format: "{0:MM/dd/yyyy}"
}, {
field: "ShipName",
title: "Ship Name"
}, {
field: "ShipCity",
title: "Ship City"
}
]
});
});
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.material.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
<div id="grid"></div>

Related

Kendo Grid Change dynamic columns title on databound

I have a kendo Grid with no columns definition because grid's fields are dynamics and I don't have any chance to know the fields before databound event.
Example:
var dataSource = new kendo.data.DataSource({
type: "aspnetmvc-ajax",
transport: {
read: {
url: appPath + "Controller/GetGridData",
dataType: "json",
type: "POST",
data: {
dataSourceID: dataSourceId
}
},
},
schema: { data: "data", total: "total"},
pageSize: 10,
serverSorting: true,
serverPaging: true,
serverFiltering: true,
});
$("#grid").kendoGrid({
dataSource: dataSource,
filterable: {
extra: false
},
dataBound: function (data) {
},
pageable: {
pageSizes: true,
pageSizes: [10, 20, 50, 100]
}
)}
Is there a way to modify columns headers dynamically on databound event or after data are loaded but before showing it to users?
I achieved "dynamic" column headers (after many infuriating troubleshooting messages back and forth by Telerik) by requesting the data prior to initialising the grid via an AJAX call then determining the column names based on the data.
$.ajax({
type: "POST",
url: "/Controller/GetGridData",
// *Important* stringify the server-bound object
data: JSON.stringify(dataSourceId),
dataType: "json",
contentType: "application/json",
async: true,
success: function(response) {
// response contains data required for grid datasource
ConstructGrid(response);
}
});
function ConstructGrid(gridData) {
var dataSource = new kendo.data.DataSource({
... attributes
data: gridData,
... more attributes
});
var columnsArray = [];
if(gridData.attributeToCheck = "someValue") {
columnsArray.push({field: attributeEqualToSomeValue, title="attributeMatchingSomeValue"});
}
else {
columnsArray.push({field: attributeNotEqualToSomeValue, title="attributeNotMatchingSomeValue"});
}
.. continue to add more columns based on data then initialise grid
$("#grid").kendoGrid({
dataSource: dataSource,
filterable: {
extra: false
},
columns: columnsArray,
pageable: {
pageSizes: true,
pageSizes: [10, 20, 50, 100]
}
)};
}
Not exactly 100% dynamic but it will change the column names based on the values retrieved from the AJAX call and AFAIK (after chatting back and forth with Telerik), truly dynamic columns are not supported by the grid control.
Check this Jsbin
`https://output.jsbin.com/lesoxes/`
In this example i have used kendo's datasource.
you will get all column details in console.
Might Help You

jsGrid won't render JSON data

I'm trying to use jsGrid in my MVC project as the client would like inline editing and filtering.
However, I cannot get it to load my JSON source into the table.
My js to load the table looks like so:
$("#jsGrid").jsGrid({
height: "50%",
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete client?",
controller: {
loadData: function (filter) {
return $.ajax({
type: "GET",
url: "RICInstrumentCode/GetData",
data: filter,
dataType: "json"
});
},
insertItem: function (item) {
return $.ajax({
type: "CREATE",
url: "/api/RICInsrumentCodeTable",
data: item,
dataType: "json"
});
},
updateItem: function (item) {
return $.ajax({
type: "UPDATE",
url: "/api/RICInsrumentCodeTable/" + item.ID,
data: item,
dataType: "json"
});
},
deleteItem: $.noop
//deleteItem: function (item) {
// return $.ajax({
// type: "DELETE",
// url: "/api/data/" + item.ID,
// dataType: "json"
// });
//}
},
fields: [
{ name: "Code", type: "text", title: "RIC Instrument Code", width: 150 },
{ name: "Descr", type: "text", title:"RIC Instrument Code Description", width: 200 },
{ name: "RICInstrumentGroupId", type: "select", title: "RIC Instrument Group", items: countries, valueField: "Id", textField: "Name" },
{ name: "Active", type: "checkbox", title: "Is Active", sorting: true },
{ type: "control" }
]
});
});
The loadData is what I've been working on.
and the JSON the is returned from get data looks like so:
[{"Id":1,"Code":"test1","Descr":"first code test","RICInstrumentGroupId":2,"Active":true},{"Id":2,"Code":"APP","Descr":"Apples and bananas","RICInstrumentGroupId":4,"Active":true},{"Id":3,"Code":"1","Descr":"1","RICInstrumentGroupId":1,"Active":true},{"Id":4,"Code":"3","Descr":"3","RICInstrumentGroupId":3,"Active":false}]
So far I have confirmed that the ajax is firing, changed my array titles to match those of the call, and ensured the return is in valid JSON, what else can I do? Why isn't this working?
I was being stupid,
The bit that sets the table height was set to a 100% in a div that had no height, this was causing the table body to render with a height of 0px, changing the height property to auto fixed it because the data was there all along.
Thanks for the advice though!
I don't know if it is required, but when I look on demo examples (OData Service).
The grid loadData function looks bit different than yours.
loadData: function() {
var d = $.Deferred();
$.ajax({
url: "http://services.odata.org/V3/(S(3mnweai3qldmghnzfshavfok))/OData/OData.svc/Products",
dataType: "json"
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
}
is accept promise rather than ajax function. so that my be the problem
Demo here: http://js-grid.com/demos/

Binding data to kendo dropdownlist

I have a kendo grid with a column that has a custom filter template which is a dropdownlist. I am having trouble populating the data into the dropdownlist.
What I want is to have the options be all of the unique values of all the records in that column.
Side question: is there any easier way to populate the dropdownlist with the unique values of the columns? As this is the most logical contents to place in the dropdown, I would hope there may be some built in way?
What I'm trying to do is have it call a service that returns JSON specifying the options.
Below I have the 3 ways I've tried to code the data-column field based on google searches that led to very old topics on this forum, which is why I hope there is a simple way. The first 2 don't work but the third (hard coding it) does work.
1) This call hits the server and returns JSON but does not populate the dropdown.
{
"field": "location_name",
"title": "Location",
"filterable": {
cell: {
template: function (args) {
args.element.kendoDropDownList({
dataTextField: "optionText",
dataValueField: "optionValue",
valuePrimitive: true,
dataSource: {
transport: {
read:
function(options) {
$.ajax({
type: "GET",
url: "/Patrol/Report.aspx/GetOptions",
data: "d",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
return msg; //tried with and without the return
}
});
}
}
}
});
},
showOperators: false
}
}
2) This call doesn't hit the server at all
{
"field": "location_name",
"title": "Location",
"filterable": {
cell: {
template: function (args) {
args.element.kendoDropDownList({
dataTextField: "optionText",
dataValueField: "optionValue",
valuePrimitive: true,
dataSource: {
transport: {
read: {
dataType: "jsonp",
url: "/Patrol/Report.aspx/GetOptions",
}
}
}
});
},
showOperators: false
}
}
3) Hard coding the datasource data: This works correctly
{
"field": "location_name",
"title": "Location",
"filterable": {
cell: {
template: function (args) {
args.element.kendoDropDownList({
dataTextField: "optionText",
dataValueField: "optionValue",
valuePrimitive: true,
dataSource:
[{"optionText": "HP","optionValue": "HP"}, {"optionText": "Loc2","optionValue": "ID2"}]
});
},
showOperators: false
}
}
Scenario 1 does not work, because you need to call options.success(...your data...) in the success callback of $.ajax():
http://docs.telerik.com/kendo-ui/framework/datasource/crud#read-loc‌​al

Why Kendo dataSouce.transport.update method do not send data to the server?

I have a Kendo UI TreeList where every row has a checkbox displayed. If the user clicks on the checkbox then a request goes to the server and save the data. Unfortunately, I did something wrong because:
the update method does not send data to the server
and the sync method is not called automatically
What I did wrong?
I think the problem around how I set up that which item has changed. As you can see I iterate over the dataset coming from dataSource.data() and the item.checked and item.dirty properties are updated. If I understand correctly the documentation then this changes should trigger the sync method. It does not trigger the sync method and this it the reason I call it in the method.
My other question is related to the data structure should be sent to the server. It is based on the schema, right? So, once I can achieve that the request sends an object to the server I should create a similar C# POCO as model and I can read the data in the webapi controller.
In the documentation there is a saveRow() method, but I cannot translate that code to angular. Can somebody help me in this case?
//this row is my problem
var treeList = $("#treeList").data("kendoTreeList");
var dataSource = new kendo.data.TreeListDataSource({
transport: {
read: {
url: configurationService.goNoGoWebApiRootUrl + 'AreaPathDependencies/Get/ChildrenMarked/' + selectedAreaPathIdFromModalService,
dataType: "json",
type: "get"
},
update:
{
url: configurationService.goNoGoWebApiRootUrl + 'AreaPathDependencies/Update/AreaPathDependencies',
dataType: "json",
type: "post"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
schema: {
model: {
id: "id",
parentId: "parentId",
fields: {
Id: { type: "number", editable: false, nullable: true },
ParentId: { type: "number", editable: false, nullable: true },
Name: { type: "string", editable: false, nullable: true },
Checked: { type: "boolean", editable: true, nullable: false }
}
}
}
});
vm.treeListOptions = {
dataSource: dataSource,
sortable: false,
editable: false,
columns: [
{
field: "checked",
title: "Selected",
template: checkBoxTemplate,
width: 32
},
{ field: "name", title: "Area Path", width: "200px", expandable: true },
{ field: "fullPath", title: "FullPath", width: "500px" },
],
save: onSave,
change: onChange,
sync: sync,
autoSync: true,
};
}
function checkboxOnclick(selectedId) {
console.log('checkboxOnclick', selectedId);
var data = vm.treeListOptions.dataSource.data();
for (var i = 0; i < data.length; i++) {
if (selectedId == data[i].id) {
data[i].set("checked", true);
//data[i].dirty = true;
}
}
vm.treeListOptions.dataSource.sync();
//console.log('flush', vm.treeListOptions.dataSource.data());
}
Well batch: true has to be set to get parameterMap working, because models parameters will be available only when the batch option is enabled. (parameterMap docs)
And to second question - I am not so sure but as noted in sync docs,
The sync method will request the remote service if:
the transport.create option is set and the data source contains new data items
the transport.destroy option is set and data items have been removed from the data source
the transport.update option is set and the data source contains updated data items
How I understand to that - to get sync method working you need to return updated records. Please check, if your server method for update/delete returns that.

Lazy Load with Scrollable {Virtual:true} not working in Kendo UI Grid

I am facing an issue to implement lazy loading in kendo ui grid.
I added scrollable virtual property and backend server side code to handle it but issues is after adding scrollable property I am unable to see scroll bar in my Grid.
Even the selected rows (20 page size) disappears off the bottom of the grid into the hidden overflow area.
Here is my code.
var managecustomerGrid = $("#customerGrid").kendoGrid({
dataSource: {
schema: {
data: "results",
total : "totalRecords",
model: {
id: "SRNUMBER",
fields: {
SRNUMBER : {type: 'number'},
CUSTOMERNAME : {type: 'string'},
DATEPAID : {type: 'string'}
}
}
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 20,
batch: false,
transport: {
read: {
type: "POST",
url: "/customer/customer.cfc",
dataType: "json",
error: function (xhr, error) {
alert('Error In Getting Customer Information.');
}
},
parameterMap: function(options, type) {
return {
ntPageNumber: options.page,
ntRowLimit: options.pageSize,
vcSortOrder: JSON.stringify(options.sort),
vcFilterCondition: JSON.stringify(options.filter)
}
}
}
},
toolbar: kendo.template($("#template").html()),
height: 600,
scrollable: {
virtual: true
},
filterable: {
operators: {
string: {
contains: "Contains",
startswith: "Starts with",
endswith: "Ends with",
eq: "Is equal to",
doesnotcontain: "Doesn't contain"
}
}
},
sortable: true,
columns: [
{ field: "SRNUMBER", title: "SR No.", width: "80px", template: "<span id='#=SRNUMBER#'>#=SRNUMBER#</span>"},
{ field: "CUSTOMERNAME", title: "Customer Name", width: "110px"},
{ field: "DATEPAID", title: "Date", width: "110px"},
{ command: ["edit","detail","cancel"], title: " ", title: "Actions", width: "130px", filterable: false, sortable: false}
]
});
Please let me know if any one find any issues. I am unable to get it.
The kendo grid does not really support Lazy Loading out of the box. It may be easier to instead just make a blank scroll-able grid (without paging), and then to populate the data with ajax calls. You can use $.merge() to append data to the data array with little to no impact on performance.
$.ajax({
url: '/getNextData',
data: { filter: 'foo', lastLoaded: $("#Grid").data("kendoGrid").dataSource.at($("#Grid").data("kendoGrid").dataSource.total()-1).ID },
dataType: "json",
success: function (newData) {
$("#Grid").data("kendoGrid").dataSource.data($.merge($("#Grid").data("kendoGrid").dataSource.data(), newData))
},
error: function (e) { console.log(e); }
});
In this ajax example I load the next data based on the current last item in the grid and a filter. I just append the response to the currently loaded data.
I faced the same issue, my problem was the controller code. Here I am posting my controller hoping it would help someone someday
public JsonResult GetJson(int? projectid,int skip, int take, int pageSize, int page)
{
using (sqlCon)
{
var myData = sqlCon.Query<Device>("Select * from workbook.dbo.TargetList", new { projectid = projectid });
var data = myData .Skip(skip).Take(pageSize).ToList();
var total = myData .Count();
var json = new { data = myData };
var jsonResult = Json(new {data= data, total= total}, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
}

Categories

Resources