Restangular, AngularJS and Kendo UI Grid - angularjs

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
};

Related

ag-grid not showing any data

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.

Adding conditional value to angular ng-table

I want to add glyphicon to a column based on row value in ng-table component .For example if row.firstProperty==row.secondProperty then the glyph be added to column.I know how to do this in angular Grid UI but although I review documentations and examples but ‍‍‍‍‍‍I did not find any way in ng-Table.Can anyone suggest a solution to my issue?
Edit:My scenario is that I have a custom directive that it is used to produce many pages with same style and functionality by getting page data and in part of it ng-table is used by defining template for my directive.
ng-table.html
<table ng-table="to.tableParams" class="table" show-filter="{{::to.showFilter}}">
<tr ng-show="to.showHeaders">
<th class="th-select" ng-repeat="column in to.columns">{{column.title}}</th>
</tr>
<tr ng-repeat="row in $data">
<td ng-repeat="column in to.columns" ng-show="column.visible" sortable="column.field" ng-click="save(row)">
{{row[column.field][column.subfield] || row[column.field]}}
<span compile="column.getValue()" ></span>
</td>
</tr>
ngTable Columns is defined in Controllers and one of the columns is html values like glyphicons and buttons that is maked base on object named actionList which is defined in each controller like below:
vm.actionList = [
{
name: 'edit',
body: function (row) {
$state.go("editrule", {ruleId: row.id});
},
glyph: 'glyphicon-pencil',
permission: $scope.permission.edit,
showCondition:"true"
},
{
name: 'view',
body: function (row) {
$state.go("showrule", {ruleId: row.id});
},
glyph: "glyphicon-eye-open",
permission: $scope.permission.watch,
showCondition:"row.modifiedDate==row.createDate"
},
{
name: 'history',
body: function (row) {
$state.go("rulehistory", {ruleId: row.id});
},
glyph: "glyphicon-info-sign",
showCondition: "row.modifiedDate!=row.createDate",
permission: $scope.permission.history
}
];
.I put the logic for creating html column to my directive to prevent repeated code from controllers and delivering it to controllers and the controller part for defining columns is as below :
vm.columns = [
{
title: $translate.instant('URL'),
translate: "URL",
field: 'url',
visible: true,
alignment: 'text-align-lg-left'
},
{
title: $translate.instant('MATCH_TYPE'),
translate: "MATCH_TYPE",
field: 'matchType',
visible: true,
alignment: 'text-align-lg-center',
filter: [{lowercase: []}]
},
{title: $translate.instant('PRIORITY'), translate: "PRIORITY", field: 'priority', visible: true,alignment: 'text-align-lg-center'},
{title: $translate.instant('SOURCE'), tanslate: "SOURCE", field: 'source', visible: true,alignment: 'text-align-lg-center'},
{title: $translate.instant('CATEGORY'), translate: "CATEGORY", field: 'category', visible: true,alignment: 'text-align-lg-center'},
{
title: $translate.instant('CREATE_DATE'),
translate: "CREATE_DATE",
field: 'createdDate',
visible: true,
alignment: 'text-align-lg-center'
},
{
title: $translate.instant('LAST_CHANGE'),
translate: "LAST_CHANGE",
field: 'modifiedDate',
visible: true,
alignment: 'text-align-lg-center'
},
{title: $translate.instant('ACTION') ,translate: "ACTION", field: 'action', visible: true,alignment: 'text-align-lg-center'},
{title: '', visible: true, getValue: htmlValue, id: "actionList"}/*actions*/
];
function htmlValue() {
return $sce.trustAsHtml(actions);
}
The action value comes from directive that contains htmls.The Directive part is as below :
scope.html = function htmlValue() {
var html = "";
/*intentionaly angular ng-repeat not used*/
for (var i = 0; i < scope.actionList.length; i++) {
scope.entry = scope.actionList[i];
scope.permission = scope.entry.permission;
scope.myglyph = scope.entry.glyph;
if (typeof scope.entry.permission == 'undefined' || scope.entry.permission == true) {
debugger
html = '<button ng-show="{{entry.condition}}" type="button" class="btn btn-list" ng-click=' + $interpolate("{{entry.name}}(row)")(scope) + '> ' +
'<span class=\"glyphicon ' + $interpolate("{{entry.glyph}}")(scope) + '\"></span>' +
'</button>' + html;
console.log("this is test");
console.log(scope.test);
}
}
}
scope.$watch('refreshDataFilter', function (newValue, oldValue) {
/*EXTRACT ACTIONS*/
for (var i = 0; i < scope.actionList.length; i++) {
var entry = scope.actionList[i];
Object.defineProperty(scope, entry.name, {value: entry.body});
Object.defineProperty(scope, entry.showCondition, {value: "aaa"});
}
/*define table data filler*/
if (newValue == true) {
renderTable();
scope.refreshDataFilter = false;
}
});
The main problem is here that if I interpolate the values of entry.showCondition I always get the value of of last item in actionList. Is there any solution that I can make html part of table base on conditions?

How can I display a grid repeater using ui-grid?

I have data of messages including {id,message,date}.
I would like to display a grid for each Date with data{message} in AngularJs using ui-grid
I was thinking of something like this:
<div ng-repeat="(item in data | groupBy: 'Date'">
<div>{{ item.Date }}</div>
<div id="grid1" ui-grid="gridOptions(item.Date) " class="grid"></div>
</div>
but it's not working!
$scope.gridOptions = function (date) {
return {
enableSorting: true,
enableFiltering: true,
data: 'data',
columnDefs: $scope.filterGrid(date),
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
};
};
$scope.filterGrid= function (date){
return [
{ field: 'id', enableFiltering: False},
{
field: 'Date', enableFiltering: false, filter: {
noTerm: true,
condition: function (searchTerm, cellValue) {
return cellValue.match(date);
}
}
},
{ field: 'Message' , enableFiltering: false },
]
}
First of all - ui-grid has a grouping feature, but this is still in beta.
You can try to use this example to group the data and build grids accordingly.
var dataSource = {};
$scope.gridOptions = {};
var generalGridOptions = {
enableSorting: true,
columnDefs: [
{ name: 'prop1' },
{ name: 'prop2' },
],
data: null
};
// group the data
for(var i = 0; i < data.length; i++){
if(!dataSource[data[i].month]){
dataSource[data[i].month] = [];
}
var obj = {};
for(var prop in data[i]){
if(prop!='month'){
obj[prop] = data[i][prop];
}
}
dataSource[data[i].month].push(obj);
}
// build the grid options
for (var item in dataSource) {
$scope.gridOptions[item] = angular.copy(generalGridOptions);
$scope.gridOptions[item].data = dataSource[item];
}
ui-grid attribute recieves a gridOptions object containing several parameters. Two of them are:
columnDefs - defining the columns and their data-binding.
data - the message objects in your case.
Look at the the documentation for further study: http://ui-grid.info/docs/#/tutorial
Code Example
template:
<div ng-repeat='item in items track by item.id' ui-grid='getItemGridOptions($index)'></div>
Passing the item index to the controller allows you to process your data. Then you can return an object containing the data and columnDefs properties. Like this:
private getItemGridOptions(index): IGridOptions {
//get the data you need for your items array using the index...
// then return the gridOptions object (I put random values)
return {
columnDefs: this.columns,
rowHeight: 24,
rowTemplate: rowtpl,
enableHorizontalScrollbar: this.uiGridConstants.scrollbars.NEVER,
enableColumnMenus: false,
enableRowSelection: true,
enableRowHeaderSelection: false,
enableFiltering: true,
modifierKeysToMultiSelect: true,
multiSelect: true,
data: null,
};
}

AngularJs component based architecture using for kendo grid

I'm very new to angular , i know little basic of angular only.
I'm trying to integrate kendo ui grid in my view using angular component.
My Angular Component :
class GetAllPostController{
constructor(API, ToastService){
'ngInject';
this.API = API;
this.ToastService = ToastService;
}
submit(){
var data = {
name: this.name,
topic: this.topic
};
this.API.all('posts').post(data).then((response) => {
this.ToastService.show('Post added successfully');
});
}
test(){
alert('');
this.gridOptions = {
sortable: true,
selectable: true,
dataSource: [
{ text: "Foo", id: 1 },
{ text: "Bar", id: 2 },
{ text: "Baz", id: 3 }
],
columns: [
{ field: "text", title: "Text" }
]
};
}
}
export const GetAllPostComponent = {
templateUrl: './views/app/components/get_all_post/get_all_post.component.html',
controller: GetAllPostController,
controllerAs: 'vm',
bindings: {},
}
My View :
<div kendo-grid k-options="gridOptions" k-ng-delay="gridOptions" ng-init="vm.test()"></div>
But it's now working. Any one please help ?
And please explain how to use scope inside componenet and view?
I'm using Laravel Angular Material
suppose u going to implement kendo inside this div
<div ng-controller="myController">
</div>
The script part
<script>
angular.controller('myController',['$scope',function($scope){
$scope.results=[];
/* ajax request and result bind to the $scope.results array */
//here you implement kendo/what ever other framework
$scope.apply(function(){
//write kendo functions inside this apply service
kendo.gridOptions = {
sortable: true,
selectable: true,
dataSource: $scope.result,
columns: [
{ field: "text", title: "Text" }
]
};
})
}])
</script>

KendoGrid with Angular ng-repeat

I have kendo-grids in Angular ng-Repeat and serach options on the grids data.
I want to refresh the grids on search.
This is my code and it doesn't refresh the grids ($("#kendoGrid1").data("kendoGrid") is undefined), what Is the fix for this?
html
<article ng-repeat="(key,val) in gridsResult" >
<h2 class="tableTitle">{{key}}</h2>
<div kendo-grid="kendoGrid{{$index}}" k-options="getGridSlice('{{key}}')"></div>
</article>
js
$scope.getGridSlice = function (index) {
var data = $scope.gridsResult[index];
return {
dataSource: {
data: data
}
},
columns: [
{ field: "aa", title: " ", attributes: { "class": "k-header",style:"text-align:center;" }, width:"33px" },
{ field: "bb", title: "IF", template: rowTemplate.replace(/XX/g, 'IF')}
],
scrollable: false,
noRecords: true,
}};
scope.onSearch function -
$("#kendoGrid1").data("kendoGrid").datasource.read();
I found the answer!
The $digest dosen't work on functions so I added k-data-source based on a scope parameter not scope function.
(you need to pull the data from the DB grouped by the grids category)
<article class="tradescreenTable" ng-repeat="(key,val) in gridsResult" ng-class="{'bestAverage': bestAverageSelected}">
<h2 class="tableTitle">{{key}}</h2>
<div kendo-grid k-data-source="{{val}}" k-options="gridOptions"></div>
</article>
And k-options
$scope.gridOptions = {
columns: [
{ field: "aa", title: " ", attributes: { "class": "k-header",style:"text-align:center;" }, width:"33px" },
{ field: "bb", title: "IF", template: rowTemplate.replace(/XX/g, 'IF')}
],
scrollable: false,
noRecords: true,
};
You also need to refresh the grid:
$("#kendoGrid1").data("kendoGrid").datasource.read();
$("#kendoGrid1").data("kendoGrid").refresh();
kendo-grid="kendoGrid{{$index}}" binds the grid to the $scope - you don't need to use jQuery for this (and besides, you're not setting an id on the DOM element, so $("#kendoGrid1") is never going to work with your code as it is now).
$scope.kendoGrid1.datasource.read();
The one caveat to this is that I haven't ever tried dynamically setting the name for a Kendo Grid, so I'm not 100% that it works.

Resources