I'm trying to create a tree view of data in server side, my data come from server with this structure:
IdObjectA: 1
NameObjectA: "NameA"
ObjectB: [{
IdObjectB: 1
NameObjectB: "NameB"
ObjectC: [{
IdObjectC: 1
NameObjectC: "NameC"
Data: [
{
...
}
]
}]
}]
I use ajax to get the response and if I debug, the data comes sucesfuly:
function createServerSideDatasource() {
return {
rowCount: undefined,
getRows: (params) => {
const response = $.ajax({
type: "POST",
url: "/Controller/GetAllDataFromDatabase",
data: { filterElementsToDatabase },
success: function (data) {
/*Get the data OK*/
var rowsData = JSON.parse(data);
params.successCallback(rowsData);
},
error: function (e, ts, et) {
params.fail();
}
});
}
};
}
The columDefs are:
const columnDefs = [
{
headerName: 'ObjectB',
children: [
{
field: 'ObjectB.IdObjectB',
headerName: "IdObjectB",
hide: true
},
{
field: "ObjectB.NameObjectB",
headerName: "NameObjectB"
},
{
headerName: 'ObjectC',
children: [
{
field: 'ObjectB.ObjectC.IdObjectC',
headerName: "IdObjectC"
},
{
field: "ObjectB.ObjectC.NameC",
headerName: "NameC",
},
{
headerName: 'Data',
children: [
{ field: 'ObjectB.ObjectC.Data.Param1', sortable: true, headerName: "Param1" },
{ field: 'ObjectB.ObjectC.Data.Param2', sortable: true, headerName: "Param2" },
{ field: 'ObjectB.ObjectC.Data.Param3', sortable: true, headerName: "Param3" },
]
}
]
}
]
}
];
and the grid options are:
gridOptions = {
rowModelType: 'serverSide',
serverSideInfiniteScroll: true,
treeData: true,
cacheBlockSize: 100,
cacheOverflowSize: 15,
maxConcurrentDatasourceRequests: 1,
infiniteInitialRowCount: 100,
maxBlocksInCache: 10,
columnDefs: columnDefs,
defaultColDef: {
sortable: true,
resizable: true,
filter: true,
enableFilter: true,
floatingFilter: true,
enableValue: true,
enableRowGroup: true,
width: 200,
},
groupHeaderHeight: 0,
suppressDragLeaveHidesColumns: true,
sideBar: {
toolPanels: [
{
id: 'columns',
labelDefault: 'Columns',
labelKey: 'columns',
iconKey: 'columns',
toolPanel: 'agColumnsToolPanel',
toolPanelParams: {
suppressSyncLayoutWithGrid: true,
suppressColumnMove: true,
},
},
],
defaultToolPanel: 'columns',
},
enableCharts: true,
enableRangeSelection: true,
autoGroupColumnDef: {
field: 'Lineas.IdCelula',
},
isServerSideGroup: (dataItem) => {
debugger;
// indicate if node is a group
var group = !!dataItem.ObjectC
return group;
},
getServerSideGroupKey: (dataItem) => {
debugger;
// specify which group key to use
return dataItem.ObjectB.ObjectC.NameC;
},
};
But when load this happen and in console don't apear exceptions or warnings about, and stay with the spinner of loading in all rows.
Find the problem, was in the server object, was with multiple elements inside like:
IdObjectA: 1
NameObjectA: "NameA"
ObjectB: [{ //<-- Array
IdObjectB: 1
NameObjectB: "NameB"
ObjectC: [{ //<-- Other Array
IdObjectC: 1
NameObjectC: "NameC"
Data: [ //<-- Other Array
{
...
}
]
}]
}]
But, you can't have a multidimensional object with arrays inside, you have to create an array of objects like:
{
IdObjectA: 1
NameObjectA: "NameA"
ObjectB: {
IdObjectB: 1
NameObjectB: "NameB"
ObjectC: {
IdObjectC: 1
NameObjectC: "NameC"
Data:
{
...
}
}
}
},
{
IdObjectA: 1
NameObjectA: "NameA"
ObjectB: {
IdObjectB: 1
NameObjectB: "NameB"
ObjectC: {
IdObjectC: 2
NameObjectC: "NameC"
Data:
{
...
}
}
}
}
Then ag-grid recieve the data and load correctly the table.
Related
I am using KendoUI - Grid component
How can I convert this into Kendo Grid:
For Eg:
I have created kendo grid (table) by using local data. As soon as I click on "Generate chart" button, above table's filter data should create the Kendo pie chart like below...
As I am new to Kendo, can somebody please suggest me the answer?
Code:
var localData = [
{
Id: 1,
userName: "John",
game: "A",
difficultyLevel: "Easy",
startTime: "25-05-2017",
endTime: "26-05-2017",
score: "210"
},
{
Id: 2,
userName: "Sam",
game: "B",
difficultyLevel: "Hard",
startTime: "04-11-2016",
endTime: "01-12-2016",
score: "4800"
},
];
var dataSource = new kendo.data.DataSource({
data: localData,
schema: {
model: {
fields: {
Id: {
type: "number"
},
userName: {
type: "string"
},
userName: {
type: "string"
},
difficultyLevel: {
type: "string"
},
startTime: {
type: "string"
},
endTime: {
type: "string"
},
score: {
type: "number"
},
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
rowTemplate: $.proxy(kendo.template($("#rowTemplate").html()), dataSource),
scrollable: true,
height: 300,
sortable: true,
filterable: false,
groupable: true,
pageable: true,
columns: [{
field: "Id",
title: "Id",
filterable: true
}, {
field: "userName",
title: "userName"
}, {
field: "game",
title: "game"
}, {
field: "difficultyLevel",
title: "difficultyLevel"
}, {
field: "startTime",
title: "startTime"
}, {
field: "endTime",
title: "endTime"
}, {
field: "score",
title: "score"
}]
});
JsFiddle
You need to prepare your data to the chart's format. Something like:
$chartContainer.kendoChart({
dataSource: {
data: localData,
schema: {
parse: function(data) {
return data.map(x => {
return {
value: Number(x.score),
category: x.userName
}
});
}
}
},
series: [{
type: "pie",
field: "value",
categoryField: "category"
}],
tooltip: {
visible: true,
template: "#= category #: #= value #"
}
});
Updated Fiddle
This is a jQuery code of my sample project to get details from application side to display in front in a grid which is build by jsGrid.
$("#part_table").jsGrid({
height: "auto",
width: "100%",
autoload: true,
editing: true,
sorting: true,
paging: true,
pageSize: 10,
inserting: true,
loadIndication: false,
filtering: true,
headerRowClass: 'table-green-header',
controller: {
loadData: function (filter) {
function.....
},
updateItem: function (item) {
function.....
}
},
fields: [
{ name: "Id", type: "number", visible: false },
{
name: "CatalogueId", type: "select", **items**: catalouges, valueField: "Id", textField: "CatalougeName", selectedIndex : -1 , title: "Catalouge Name", align: "center"
},
{ name: "DistributorPrice", type: "number", title: "Distributor Price", align: "center", filtering: false, sorting: false },
{ name: "IsActive", type: "checkbox", filtering: false, sorting: false },
{ type: "control" }
],
rowClick: function (args) {
return false;
},
});
Can anyone say how to get a list of items to field by calling to application side via AJAX call ?
Thanks
Load items in advance and then use result in the grid field config, e.g.:
$.ajax({
type: "GET",
url: "/countries/"
}).done(function(countries) {
countries.unshift({ id: "0", name: "" });
$("#jsGrid").jsGrid({
...,
fields: [
...
{ name: "country_id", title: "Country", type: "select", width: 100, items: countries, valueField: "id", textField: "name" }
]
});
});
You can find an example in the jsgrid sample project
You can do multiple simultaneous requests before the grid launches
$.when(
$.get("/api/v1/clients", function(clients) {
db.clients = clients;
}),
$.get("/api/v1/owners", function(owners) {
db.owners = owners;
})
).then(function() {
$("#jsGrid").jsGrid({
...,
fields: [
{ name: "client", title: "Client", type: "select", items: db.clients, valueField: "name", textField: "name" },
{ name: "owner", title: "Owner", type: "select", items: db.owners, valueField: "short_name", textField: "short_name" },
]
});
});
you write the ajax call in loadData of the controller.. something like:
controller: {
loadData: function(filter) {
return $.ajax({
type: "GET",
url: "/api/data",
data: filter,
dataType: "json"
});
}
}
further reference https://github.com/tabalinas/jsgrid-webapi
I have an Observable Array of items that creates components with a parameter.
Within each component, I use that parameter to query for data (through AJAX). I return that data into an Observable Array and use that Array as a data source for a KendoUI chart.
Example of list of created components with a parameter:
<csglist params="account:'08167526'"></csglist>
<hr>
<csglist params="account:'0873458'"></csglist>
<hr>
<csglist params="account:'0828337'"></csglist>
<hr>
<csglist params="account:'086778'"></csglist>
call that gets the data
getCategory = function () {
self.categoryChart([]);
xhr_get(cont.publish + 'api/dbmain/getCategory', { 'id': params.account }).done(function (allData) {
var mappedLogs = $.map(allData, function (item) { return new categoryData(item) });
self.categoryChart(mappedLogs);
buildChart();
})
}
function buildchart(){
$(document).ready(createChart);
$(document).bind("kendo:skinChange", createChart);
}
the create chart
function createChart() {
$("#" + self.act() + "chart").kendoChart({
dataSource: {
data: ko.toJS(self.categoryChart)
//, sort: { field: "category", dir: "asc" }
},
title: {
text: self.type()
},
legend: {
visible: true,
position: "bottom"
},
seriesDefaults: {
type: "bar",
stack: true
},
series: [{
field: "sales",
name: "Current Sales",
color: "#66110F"
}, {
field: "opp",
name: "Opportunity",
color: "#E65F5B"
}],
valueAxis: {
// max: 180,
line: {
visible: false
},
minorGridLines: {
visible: true
},
visible: false
},
categoryAxis: {
field: "category",
majorGridLines: {
visible: false
}
},
tooltip: {
visible: false,
template: "#= series.name #: #= value #"
}
});
}
But when the components are all created, only the last one has data.
Can anyone tell me why is this happening?
when I changed the the buildChart = function to self.buildChart = function, it works!
I'm currently implementing a kendo grid and i'm populating it with local data.
That is; I have generated a JSON string from my action and supplying that string on the view page.
In the end i would like to know if it is possible to implement full CRUD functions with local data?
here's a sample of the code written so far;
<div id="example" class="k-content">
<div id="grid"></div>
<script>
$(document).ready(function() {
var myData = ${coursemodules},
dataSource = new kendo.data.DataSource({
data: myData,
batch: true,
pageSize: 30,
schema: {
model: {
id: "id",
fields: {
id: { editable: false, nullable: true},
name: { type: "string", validation: { required: true }},
qualificationLevel: { type: "string", validation: { required: true }},
description: { type: "string", validation: { required: true }},
published: { type: "boolean" },
gateApprove: { type: "boolean" },
duration: { type: "number", validation: { min: 1, required: true } },
academicBody: { type: "string" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
height: 350,
scrollable: true,
sortable: true,
pageable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{
field: "id",
title: "ID",
width: '3%'
},
{
field: "name",
title: "Course Title",
width: '20%'
},
{
field: "description",
title:"Description",
width: '35%'
},
{
field: "published",
title: "Published",
width: '7%'
},
{
field: "gateApprove",
title: "Gate Approve",
width: '7%'
},
{
field: "duration",
title: "Duration",
width: '5%'
},
{
field: "academicBody.shortName",
title: "Academic Body",
width: '10%'
}
],
editable: true
});
});
</script>
</div>
I have realise that for the datasource, you have to declare transport to implement the CRUD. However, I need to declare "data". I tried declaring both transport and data. That doesn't seem to work.
Yes you can Here is JSFiddle Hope this will help you.
// this should be updated when new entries are added, updated or deleted
var data =
[{
"ID": 3,
"TopMenuId": 2,
"Title": "Cashier",
"Link": "www.fake123.com"},
{
"ID": 4,
"TopMenuId": 2,
"Title": "Deposit",
"Link": "www.fake123.com"}
];
$("#grid").kendoGrid({
dataSource: {
transport: {
read: function(options) {
options.success(data);
},
create: function(options) {
alert(data.length);
},
update: function(options) {
alert("Update");
},
destroy: function(options) {
alert("Destroy");
alert(data.length);
}
},
batch: true,
pageSize: 4,
schema: {
model: {
id: "ID",
fields: {
ID: {
editable: false,
nullable: true
},
TopMenuId: {
editable: false,
nullable: true
},
Title: {
editable: true,
validation: {
required: true
}
},
Link: {
editable: true
}
}
},
data: "",
total: function(result) {
result = result.data || result;
return result.length || 0;
}
}
},
editable: true,
toolbar: ["create", "save", "cancel"],
height: 250,
scrollable: true,
sortable: true,
filterable: false,
pageable: true,
columns: [
{
field: "TopMenuId",
title: "Menu Id"},
{
field: "Title",
title: "Title"},
{
field: "Link",
title: "Link"},
{
command: "destroy"}
]
});
When binding local data, the Grid widget utilizes an abstraction that represents a local transport. Therefore, it does not require a custom transport; modifications made in the grid are reflected to the bound data source. This includes rollbacks through a cancellation.
There is fully functional example of this in telerik documentation
What you need is define transport block in dataSource object with custom CRUD funtions which update local source.
transport: {
create: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.data.ID = localData[localData.length-1].ID + 1;
localData.push(options.data);
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
read: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
options.success(localData);
},
update: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID == options.data.ID){
localData[i].Value = options.data.Value;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(options.data);
},
destroy: function(options){
var localData = JSON.parse(localStorage["grid_data"]);
for(var i=0; i<localData.length; i++){
if(localData[i].ID === options.data.ID){
localData.splice(i,1);
break;
}
}
localStorage["grid_data"] = JSON.stringify(localData);
options.success(localData);
},
}
(i posted this on the extjs forum too but recon SO is probably busier)
HI
I'm passing down the following json to a direct store:
{
"type": "rpc",
"tid": 2,
"action": "DirectReportDesigner",
"method": "GetReports",
"result": {
"total": 1,
"data": [{
"id": 1,
"FullTypeName": null,
"title": "test",
"useGroupedColConfig": false,
"groupTextTemplate": "{'ProviderName': ' Contract Number -- {gvalue}','ProviderName': ' Provider Name -- {gvalue}'}",
"groupHeaders": null,
"groupFields": "['CostElement2', 'CostElement3', 'CostElement4']",
"groupedHeaders": false,
"jsonUrl": "report/BudgetManagerBudgetData.rails",
"menuType": "rptmid",
"actualType": "rptmid",
"ignoreCols": "1",
"getRowClass": "settings.utils.highlightRowWhenCellEmptyClass",
"deleted": false,
"fitToScreen": false,
"isCopyOf": 0
}]
}
}
here is what the js code looks like:
Ext.extend(Ideal.ReportDesigner.ReportGrid, Ideal.UI.BaseGrid, {
pageSize: 25,
afterRender: function() {
this.getStore().load({
params: {
start: 0,
limit: 25
}
});
Ideal.ReportDesigner.ReportGrid.superclass.afterRender.apply(this, arguments);
},
header: false,
view: new Ext.grid.GridView({
autoFill: true
}),
cm: new Ideal.UI.ColumnModel([{
header: 'Report Name',
id: 'nameCol',
sortable: true,
dataIndex: 'title'
}, {
header: 'Json URL',
sortable: true,
dataIndex: 'jsonUrl'
}, {
header: 'Group Text Template',
sortable: true,
dataIndex: 'groupTextTemplate'
}, {
header: 'Group Headers',
sortable: true,
dataIndex: 'groupHeaders'
}, {
header: 'Group Fields',
id: 'groupFieldsCol',
sortable: true,
dataIndex: 'groupFields'
}, {
header: 'Grouped Headers',
sortable: true,
dataIndex: 'groupedHeaders'
}, {
header: 'Fit to Screen',
sortable: true,
dataIndex: 'fitToScreen'
}, {
header: 'Ignore Cols',
sortable: true,
dataIndex: 'ignoreCols'
}, {
header: 'Get Row Class',
sortable: true,
dataIndex: 'getRowClass'
}
]),
initComponent: function() {
var ds = new Ext.data.DirectStore({
directFn: DirectReportDesigner.GetReports,
paramsAsHash: false,
paramOrder: 'start|limit|sort|dir',
root: 'data',
idProperty: 'id',
totalProperty: 'total',
sortInfo: {
field: 'title',
direction: 'ASC'
},
fields: [{
name: 'id'
}, {
name: 'title'
}, {
name: 'useGroupedColConfig'
}, {
name: 'groupTextTemplate'
}, {
name: 'groupHeaders'
}, {
name: 'groupFields'
}, {
name: 'groupedHeaders'
}, {
name: 'jsonUrl'
}, {
name: 'menuType'
}, {
name: 'actualType'
}, {
name: 'fitToScreen'
}, {
name: 'ignoreCols'
}, {
name: 'getRowClass'
}, {
name: 'isCopyOf'
}
],
remoteSort: true
});
var pager = new Ext.PagingToolbar({
store: ds,
displayInfo: true,
pageSize: this.pageSize
});
var config = {
store: ds,
bbar: pager
};
Ext.apply(this, Ext.apply(this.initialConfig, config));
Ideal.ReportDesigner.ReportGrid.superclass.initComponent.apply(this, arguments);
}
});
the grid renders ok, the server code to get the json fires ok, but the store never loads the data. i know it's being passed back as i can see it in firebug and that's how i pasted it above.
can anyone see anything obvious here?
cheers
w://
I've always defined store's fields as an array of strings, not as objects.
fields: ['id','title','useGroupedColConfig', ...]
i managed to sort this - it was the name of the c# variable that was getting serialized that was throwing it - why i have no idea!!!