I am using ag-grid with angularjs. so in controller I am populating rows of grid with the sql DB source. For this I am making webapi call which returns array of object. Following is the code.
var module = angular.module("crud", ["agGrid"]);
module.controller("crudCtrl", function ($scope, $http) {
var columnDefs = [
{ headerName: "Roll No", field: "RollNo", editable: true },
{ headerName: "Name", field: "Name", editable: true },
{ headerName: "Place", field: "PlaceName", editable: true },
{ headerName: "Birth Date", field: "dob", editable: true }
];
$scope.gridOptions = {
columnDefs: columnDefs,
rowData: [],
headerHeight: 42,
rowHeight: 32
};
$http.get("api/Student/GetAllStudents").then(function (response) {
$scope.gridOptions.rowData = response.data;
}, function (error) {
console.log('Oops! Something went wrong while saving the data.')
});
});
but when I run the page it is not showing any data. When I debug and see it returns records in response.data as an array of object as array[12]. but it is not showing the same in grid. If instead of response.data I assign my own array similar to what response returns, then it renders the data. So, where is the issue?
We had a similar problem. You may need to use gridOptions.onGridReady
onGridReady: () => {
//setup first yourColumnDefs and yourGridData
//now use the api to set the columnDefs and rowData
this.gridOptions.api.setColumnDefs(yourColumnDefs);
this.gridOptions.api.setRowData(yourGridData);
},
Make sure the columnDefs field matches the fields in your rowData array.
You need to configure rowModelType as 'serverSide' in gridOptions if the data comes from server, otherwise the rowModelType as '' for loading data from local.
Related
I'm using kendo-ui grid for AngularJs and want to activate virtualization of remote data functionality. For testing I have set pageSize: 5.
Below is description of virtualization of remote data from telerik site:
There are cases when you may need to operate with large amount of data
in the grid, and fetching and processing this data at once would
impose a performance penalty due to limited browser resources.
Luckily, the Kendo UI grid has a solution called data virtualization
that alleviates any slowdowns when operating with huge volumes of
data. When enabled via the scrollable->virtual configuration option,
it displays a vertical scrollbar for the grid content and renders only
the number of items set via the pageSize property of the grid data
source. After you drag the scrollbar and the pageSize is exceeded, it
makes automatic requests to retrieve and render the next set of grid
rows. Both local and remote data are supported with the grid
virtualization feature, whereas in this demo the records are obtained
from a remote endpoint.
Also I have set following:
HTML:
<div kendo-grid k-options="mainGridOptions" id="historyGrid" style="width: auto;"></div>
JS for grid:
var vm = $scope;
vm.viewMode = {
mainGridOptions: {
visible: true
}
};
vm.mainGridOptions = {
columns: [
// here columns
],
onRegisterApi: function (gridApi) {
vm.gridApi = gridApi;
},
dataSource: {
schema: {
model: {
fields: {
YearBalance: { type: 'number' },
Typezalezh: { type: 'string' },
License: { type: 'string' },
ObjectName: { type: 'string' },
ZalezhName: { type: 'string' },
PlastName: { type: 'string' },
Category: { type: 'string' },
Parameter: { type: 'string' },
LastVal: { type: 'string' },
Val: { type: 'string' },
Operation: { type: 'string' },
EndT: { type: 'date' }
}
}
},
pageSize: 5,
transport: {
read: function(e) {
dataservice.getImportResultReport().then(function(data) {
e.success(JSON.parse(data));
console.log(data);
});
}
}
},
serverPaging: true,
height: screen.height - 330,
minwidth : 1190,
batch: true,
scrollable: {
virtual: true
},
sortable: true,
serverSorting: true,
filterable: {
extra: false,
operators: {
string: {
// here filters
},
number: {
// here filters
},
date: {
// here filters
}
}
}
};
On telerik site (Official website), it says that nothing more needs to be done.
On scrolling, I should see a request to the server which in my case should be a dataservice.getImportResultReport() call. But this does't happen. This function is called only once and all data is returned.
May be it's occurring because I have not set type: "odata"? But I use data source of another type.
How to use this functionality?
Add k-scrollable directive as follows in your html that renders your kendo grid:
<div kendo-grid k-data-source="mainGridOptions" k-scrollable="{virtual:true}"></div>
Also you have to use k-data-source directive for your dataSource. Hope it helps.
Working demo plunkr
I have a Kendo UI grid, which is bound to an KendoObservableArray. I am using inline edit mode. And my options are declared as below :
valueMapCtrl.lookupMappingDetails = new kendo.data.ObservableArray([]);
valueMapCtrl.gridOptions = {
dataSource: new kendo.data.DataSource({
type: "json",
transport: {
read: function (options) {
options.success(valueMapCtrl.lookupMappingDetails);
},
update: function (options) {
console.log("Update", options);
options.success(options.data);
},
create: function (options) {
console.log("Create", options);
options.data.mappingId = mappingId;
mappingId = mappingId + 1;
options.success(options.data);
},
destroy: function (options) {
console.log("Delete", options);
options.success(options.data);
},
parameterMap: function (options, type) {
// this is optional - if we need to remove any parameters (due to partial OData support in WebAPI
console.log(options, type);
if (operation !== "read" && options.models) {
return JSON.stringify({models: options});
}
},
},
change: function (e) {
console.log("change: " + e.action);
// do something with e
},
error: function (e) {
// handle error
alert("Status: " + e.status + "; Error message: " + e.errorThrown);
},
//data: valueMapCtrl.dynamicData,
schema: {
model: {
id: "mappingId",
fields: {
mappingId: {editable: false, nullable: false, defaultValue: 0},
Col1: {
type: "string",
validation: {
required: true
}
},
Col2: {
type: "string",
validation: {
required: true
}
}
}
}
},
pageSize: 10,
batch: false
}),
columns: [{
field: "col1",
title: "Column 1"
}, {
field: "col2",
title: "Column 2"
}, {
command: /*"destroy"*/ ["edit", "destroy"],
title: " ",
width: "200px"
}],
selectable: "multiple cell",
allowCopy: "true",
//save: function (e) {
// console.log("Save", e);
//},
toolbar: ["create"],
height: 300,
navigatable: true,
filterable: true,
sortable: true,
pageable: true,
editable: "inline"
};
Add record : create fires correctly
Delete record: destroy fires correctly
Update record : nothing happens, no error, all I see in change event sync() action.
But If I declare save as well in my options, that fires correctly.
save: function (e) {
console.log("Save", e); //This fires on each update
},
I am not sure what is wrong in above declaration; browsed through a lot of forums/questions for similar issue but could not get it working. Any help ?
I was able to get it working, posting here in case anyone gets the same issue.
valueMapCtrl.lookupMappingDetails = new kendo.data.ObservableArray([]);
I changed this observable array to normal array and things worked fine after that :
valueMapCtrl.lookupMappingDetails =[];// new kendo.data.ObservableArray([]);
Also, with observable array, I was facing another issue; where cancelling of edit was removing ALL ROWS from the grid. That also worked correctly after this change. Not sure of the reason though and couldn't find any explanation in telerik docs (Whatever I could search).
I am using Kendo UI Grid with row filters. i am facing filters options issue. I am using Filterbale.cell.template for filters to display kendo autoComplete.
Issue is as displayed in image autocomplete options are not updating on selecting of one of the filters.
Below is my html
<div ng-controller="VehiclesController" class="my-grid" >
<kendo-grid options="vehiclesGridOption">
</kendo-grid>
</div>
Below is my Controller
$scope.vehiclesGridOption = {
dataSource: {
schema: {
id: "_id",
model: {
fields: {
make: {type: "string"},
model: {type: "string"},
year: {type: "number"}
}
}
},
transport: {
read: function (e) {
vehicleService.vehicles().then(function (response) {
e.success(response);
console.log(response.length);
}).then(function () {
console.log("error happened");
})
}
},
pageSize: 12,
pageSizes: false,
},
sortable: {
mode: "multiple",
allowUnsort: true
},
filterable: {
mode: "row"
},
pageable: {
buttonCount: 5
},
columns: [
{
title: "",
template: '',
width: "3%" // ACTS AS SPACER
},
{
field: "make",
title: "Make",
filterable: {
cell: {
operator: "contains",
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "make",
dataValueField: "make",
valuePrimitive: true,
placeholder: "Make",
});
}
}
},
width: "29%",
}, {
field: "model",
filterable: {
cell: {
operator: "contains",
template: function (args) {
console.log(args);
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "model",
dataValueField: "model",
valuePrimitive: true,
placeholder: "Model",
});
}
}
},
title: "Model",
width: "29%",
}, {
field: "year",
title: "Year",
filterable: {
cell: {
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "year",
dataValueField: "year",
placeholder: "Year",
suggest: true,
ignoreCase: true,
filter: "gte"
});
}
}
},
width: "29%",
},
{
field: "",
title: "Edit",
template: '<a class=\"k-link text-center grid-edit-btn vehicle-grid-edit-btn\" ui-sref="vehicleDetails({\'id\': \'#=_id #\' })"><span class=\"icon-editpencil icon-grid\"></span></a>',
width: "10%",
}],
};
Below is the Issue if user selects the Make in the first column filter then Model filter should display only selected make models like Honda (make)-> Accord , Civic ..etc but its displaying all unique values irrespective of model filter..
Kendo filter row uses the same dataSource from the grid component, just providing unique values. Since the autocomplete components are initialized when the grid dataSource is empty, they always show all the values.
You can manually filter based on current filter row values.
Firstly, add ids for your coresponding autocomplete components i.e. inside template functions:
args.element.attr('id', 'make');
//<...>
args.element.attr('id', 'model');
//<...>
args.element.attr('id', 'year');
Then add a data bound event to the grid (since autocomplete components do not fire change events when filters are cleared).
$scope.vehiclesGridOption = {
//...
dataBound : function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
});
}
}
Or if you also want to filter by "Year" column, it could go like this:
$scope.vehiclesGridOption = {
//...
dataBound: function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
var model = $('#model').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
var yearFilter = {filters: [], logic: 'and'};
if (make) {
yearFilter.filters.push({field: 'make', operator: 'eq', value: make });
}
if (model) {
yearFilter.filters.push({field: 'model', operator: 'eq', value: model });
}
$('#year').data('kendoAutoComplete').dataSource.filter(yearFilter.filters.length ? yearFilter : null);
});
}
}
My problem is I'm using the kendo-grid as follows
in index.html
<table kendo-grid k-options="gridOptions" k-ng-delay="gridOptions" id="grid">
<thead>
<tr>
<th data-field="type">Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="asset in assets">
<td>{{asset.type}}</td>
</tr>
</tbody>
</table>
and using a factory for restangular
angular.module('myApp')
.factory('assetFactory', function (Restangular) {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('my/service/url');
});
});
then in assetCtrl
assetFactory.all('cases').getList().then(function(assets) {
$scope.assets = assets;
});
.......
.......
$timeout(function(){
$scope.gridOptions = {
sortable: true,
selectable: true,
scrollable: true,
groupable: true,
height:790,
pageable: {
pageSize: 25,
input: true
}
};
}, 500);
now it is working but I'm not able to add more attributes for columns or updating because everything is generated in the index.html so I feel like I have no control on it.
So I want to make it something like this
in index.html just
<kendo-grid k-options="gridOptions" k-ng-delay="gridOptions">
</kendo-grid>
and keeping the factory as it is (using Restangular)
then in assetCtrl
var myData = new kendo.data.dataSource{
data: **// assign the assets here**
}
$timeout(function(){
$scope.gridOptions = {
dataSource: myData,
columns: [
**//fields with attributes like filtering for each col**
]
sortable: true,
selectable: true,
scrollable: true,
groupable: true,
height:790,
pageable: {
pageSize: 25,
input: true
}
};
}, 500);
Also can anyone tell me how should my service return look like ?? json array or .... ?
Any help ?
Thanks in advance
I know this question is a few months old, but I had to figure out how to make Restangular and Kendo UI Grid play nice today. I eventually came across the kendo.data.DataSource api as a reference: http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read
Note: There's some solutions out there recommending using Datasource.push or DataSource.add and essentially transferring your json array via a for-loop. That's a bad idea since .add and .push both trigger an update.
Anyway, the solution using DataSource.transport.read:
Angular HTML Template:
<kendo-grid k-options="mainGridOptions"></kendo-grid>
Pertinent Controller Code:
// Set the columns of the grid. 'title' is the Label, 'field' is the corresponding json field name.
var kGridColumns = [
{title: "Asset Type", field: "asset"},
{title: "Asset Case Name", field: "name"},
{title: "Asset Case ID", field: "id"},
];
// Create a new Kendo DataSource and set the transport.read to a function.
var kDataSource = new kendo.data.DataSource({
pageSize: 10,
transport:{
read:function(e){
var assetListPromise= assetFactory.all('cases').getList();
assetListPromise.then(function(resp){
// Use .plain() to strip out all the excess Restangular features from the response
var plain = resp.plain();
// Pass your data back to the datasource/grid
e.success(plain);
});
assetListPromise.catch(function(resp){
var msg = "Issue loading asset cases:"+JSON.stringify(resp);
e.error(msg)
});
}
}
});
// Set the scope object with our columns and datasource config
$scope.mainGridOptions = {
dataSource: kDataSource,
sortable: true,
pageable: true,
columns: kGridColumns
};
I've got a datagrid configured as follows:
<script>
angular.module("KendoDemos", [ "kendo.directives" ]);
function MyCtrl($scope) {
$scope.mainGridOptions = {
dataSource: {
transport: {
read: {
url: "http://localhost:8090/rest/mycodeapi/Salesman?app_name=mycode&fields=FirstName%2C%20LastName&include_count=true",
dataType : 'jsonp',
type: 'GET',
beforeSend: function (req) {
req.setRequestHeader('Authorization', 'b3pilsnuhsppon2qmcmsf7uvj6')
}
},
parameterMap: function(data, type) {
if (type == "read") {
// send take as "$top" and skip as "$skip"
return {
order: data.sort[0]['field'] + ' ' + data.sort[0]['dir'],
limit: data.pageSize,
offset: data.skip
};
}
}
},
schema: {
data : 'record',
total: 'meta.count'
},
pageSize: 5,
serverPaging: true,
serverSorting: true,
sort: { field: "SalesmanID", dir: "asc" }
},
sortable: true,
pageable: true,
mobile: 'phone',
columns: [{
field: "FirstName",
title: "First Name"
},{
field: "LastName",
title: "Last Name"
}]
};
}
</script>
Problem is: on 1st click of the any column, say FirstName, it sorts by ascending order which is fine.
On 2nd click it sorts by descending: still the expected behaviour.
On the 3rd click however, nothing happens and the console reveals "Uncaught TypeError: Cannot read property 'field' of undefined ". This means something happens to the data.sort array after the 2nd consecutive click.
Would appreciate any pointers.
On third click the sorting is removed. You can modify your script like following:
if (type == "read") {
var params = {
limit: data.pageSize,
offset: data.skip
};
if (data.sort && data.sort.length > 0)
params.order = data.sort[0]['field'] + ' ' + data.sort[0]['dir'];
return params;
}
I know this is a bit late, but I was facing the same challenge, and this is what I did to resolve the issue.
Change
sortable: true,
to
sortable: {
allowUnsort: false
},