$scope.gridOptions.api.setRowData not working - angularjs

I am using ag-grid . But I am not able to paint the data from json using $scope.gridOptions.api.setRowData method.. Only headers are displayed.Data is not painted in UI.
Find the code below
myApp.controller("getProfitabilityDetailsController", function($scope, $http) {
var columnDefs = [
{headerName: 'quantity',field: 'quantity', width: 150},
{headerName: 'finyear',field: 'finyear', width: 150}
];
$scope.gridOptions = {
columnDefs: columnDefs
};
$http.get("partials/profitability/mock/profitability_details.json")
.then(function(result){
$scope.gridOptions.api.setRowData(result.data.response);
});
});

A classic error to check when using ag-grid :
Does the div containing the ag-grid directive has a raw height specified (raw = in px) or any parent dom element. If not add a style="height:500px" for instance.
Otherwise i need to see the html you're using and the format of your json file.

try this instead:
$http.get("partials/profitability/mock/profitability_details.json")
.then(function(result){
$scope.gridOptions.api.setRowData(result.data);
});
Looks like you had an extra property name on return

Related

AngularJs - ag-grid rowData using "controller as" syntax

[Update] This Plunker does what I want, but :
it uses ui-grid, rather than ag-grid.
it injects the grid into the module, rather than just the single controller which uses it.
I presume that these changes would be straightforward & will try to work them into my code when I get home in about 14 hours time.
If anyone wants to fork that Plunk and make those changes, I will award a bounty, as this is a good basic start point demo for others wanting to do the same, so that a Plunker would be of general help.
I am tantalizingly close, but
Cannot read property 'setRowData' of undefined (caused by "<ui-view class="ng-scope ng-binding">")"TypeError: Cannot read property 'setRowData' of undefined
I am using "controller as" syntax, hence the Self; (Self = this;). That is working fine, my problem is when I try to set the rowData for an ag-grid in the templateURL of a ui-router state.
It's much to big to post, but here's the relevant stuff:
<div id="currentCandidatesGridDiv"
ag-grid="Search_result_controller.currentCandidatesGrid"
class="ag-theme-balham red_border"
style="height: 30%; width:90%">
</div>
// lookup the container we want the Grid to use
const currentCandidatesGridDiv = document.querySelector('#currentCandidatesGridDiv');
// create the grid passing in the div to use together with the columns & data we want to use
new agGrid.Grid(currentCandidatesGridDiv, Self.currentCandidatesGrid);
Self.currentCandidatesGrid =
{
columnDefs: [
{ headerName: "Candidate", field: "candidate_name", sortable: true },
{ headerName: "Skills", field: "skills", sortable: true },
{ headerName: "Start date", field: "start_date", sortable: true }
],
rowData: [],
pagination: true,
paginationAutoPageSize: true,
};
Was I correct to rowData: [], or ought I to have rowData: <someVariable>?
Then I calculate the row data into an array, Self.currentCandidatesGridRowData.
When I try to Self.currentCandidatesGrid.api.setRowData(Self.currentCandidatesGridRowData); I get error showing above.
I searched, but cannot find a working Plunker using the controller as syntax.
[Dupers] 1) the "dupe" question does not have an answer, so is of no use to me
2) my question is specifically about using Self.xxxGrid.api.setRowData(Self.xxxGridRowData); with the `controller as syntax. Pleas ere-open. Thnaks
DEMO of ag-Grid with AngularJS using "controller As" syntax
When the ag-Grid script loads, it does not register with AngularJS 1.x. This is because AngularJS 1.x is an optional part of ag-Grid and you need to tell ag-Grid you want to use it:
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
For more information, see
Ag-Grid Documentation - Basic AngularJS 1.x Example
The DEMO on PLNKR
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
.controller("exampleCtrl", function() {
var columnDefs = [
{headerName: "Make", field: "make"},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
var rowData = [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
this.gridOptions = {
columnDefs: columnDefs,
rowData: rowData
};
})
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
<script src="//unpkg.com/angular/angular.js"></script>
<script src='//unpkg.com/#ag-grid-community/all-modules/dist/ag-grid-community.min.js'>
</script>
<body ng-app="example" ng-controller="exampleCtrl as $ctrl"
style="height: 100%">
<div ag-grid="$ctrl.gridOptions" class="ag-theme-balham"
style="height: 100%;">
</div>
</body>
Was I correct to rowData: [], or ought I to have rowData: <someVariable>?
You can even ignore this property in gridOptions, but the difference is that:
if you will define rowData as an empty array - grid will render handle it as 'No rows to show', but if you will not define it, grid will show 'Loading...' - which is more correct, with a delayed request case.
Besides, you can handle overlay logic by yourself for more details check here.
Now, as I said in comments
Cannot read property 'setRowData' of undefined
this issue could be caused by using the wrong reference.
First, take a look and check this answer with ag-grid developer comment also.
Secondly, about an issue itself:
.controller('yourController', [function() {
var Self = this; // here's your controller reference
// then you will have columns and rowData (probably)
// but the most important part is here
Self.currentCandidatesGrid = {
... // anything that you need
onGridReady: gridReady // major point for future api reference
}
function gridReady(params){
Self.gridApi = params.api;
Self.columnsApi = params.columnsApi;
}
}]);
And after gridReady you would be able to use grid API methods via Self.gridApi
Demo

How to get the rowcol object of a cell DOM element selected in the grid of UIGrid?

I'm using UIGrid.
How can I get the row-column object of a selected cell's DOM element in the grid?
$(".ui-grid-cell-focus") this gives you the HTML DOM of the currently focused/selected cell. I'm trying to get the uiGrid row-col object using this HTML DOM value. I dont know how to!
Please try as shown below.
js
var editCellTemplate = '<div class="ngCellText"><button class="btn btn-icon-only
green height-28" ng-click="grid.appScope.editProperty(row.entity.id)"><i
class="fa fa-edit"></i></button></div>';
vm.yourGridOptions = {
appScopeProvider: vm,
flatEntityAccess: false,
fastWatch: true,
showHeader: false,
columnDefs: [
{
name: 'id',
field: 'id',
width: 240,
},
{
name: 'Edit',
cellTemplate: editCellTemplate,
width: 40,
}
],
data: []
};
//edit property
vm.editProperty = function (id) {
// your logic here
};
You could try in your gridOptions declaration:
onRegisterApi: function(gridApi){
gridApi.cellNav.on.navigate($scope,function(newRowcol, oldRowCol){
console.log(newRowcol);
});
}
Just be sure to inject ui.grid.cellNav into your angular module and ui-grid-cellNav in your grid directive view. newRowcol is your row-col object

Can't display date from server in ui-grid columnDef header with angularFire

I started working with ui-grid version 3 a couple of weeks ago and was able to successfully bring firebase data objects in my grid.
Now, I'd like to display the date from the server every time a form entry is submitted, even though the date field is not a field in the form, I will need to show it on the grid to have a date reference for every successful submission.
In my controller I've changed code to better reflect question:
var timeRef = new Firebase('https://xxc16.firebaseio.com/calls');
timeRef.set('time')
.set(Firebase.ServerValue.TIMESTAMP)
.on("value", function(snapshot){
var currentServerTime = snapshot.val();
console.log('The server time set for this call is:'+currentServerTime);
});
$scope.gridOptions = {
columnDefs: [
{name:'Created On', field: 'createdOn', width:120,cellTemplate:"<div class='ui-grid-cell-contents'> {{3+3}} -{{grid.appScope.createdOn | date:'MM/dd/yy h:mm:ss a'}}</div>"},
{name:'firstname', field: 'firstname'},
{name:'lastname', field: 'lastname'},...
I have:
firebase.js 2.3.1
angularfire.min.js 1.1.3
data structure:
To bind a value to a cell template in ui-grid, its better to go with appScopeProviver.
You can define the appScopeProvider in your ui-grid configuration object as follows,
appScopeProvider: {}
now any value exposed on appScopeProvider can be accessed inside the templates using grid.appScope.yourVariableName
So in your case, you need to expose your value on appScopeProvider as follows,
appScopeProvider {
createdOn: $scope.createdOn
}
Now you can access the same in your template as follows,
cellTemplate:"<div class='ui-grid-cell-contents'>{{grid.appScope.createdOn | date:'MM/dd/yy h:mm:ss a'}}</div>"
Your value will be bound to your template.
However, if your values will change per row, instead of property you can define a function which can return the date.
For e.g
appScopeProvider: {
getCreatedOn: function() {
// your logic here to get the created on date.
// return your value.
}
}
Below I have provided a sample snippet where I am creating new column (created date) and binding my value present on $scope.createdOn defined in controller.
var app = angular.module("myapp", ["ui.grid"]);
app.controller("uiGridCntrl", ["$scope", function($scope){
$scope.myData = [{name: "Moroni", city: "Washington"},
{name: "Tiancum", city: "NY"},
{name: "Jacob", city: "LA"}];
$scope.createdOn = new Date();
$scope.gridData = {
data: 'myData',
columnDefs: [
{field: 'name', displayName: 'Name'},
{field: 'city', displayName: 'City'},
{field: 'Created On', displayName: 'Created Date', cellTemplate:"<div class='ui-grid-cell-contents'>{{grid.appScope.createdOn | date:'MM/dd/yy h:mm:ss a'}}</div>"}
],
appScopeProvider: {
'createdOn': $scope.createdOn
}
}
}]);
.ui-grid-style {
height: 400px;
width: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.js"></script>
<div ng-app="myapp">
<div ng-controller="uiGridCntrl">
<div class="ui-grid-style" ui-grid="gridData"></div>
</div>
</div>
Firebase.ServerValue.TIMESTAMP is a placeholder that is used at the server to generate a server-based timestamp. It is not a JavaScript Date object. Thus, you cannot use it as a Date object. A read of the API docs for TIMESTAMP should make this clear.
Locally, you should simply use new Date() or Date.now().
$scope.calldate = new Date();
If you really want to confuse your users by showing them the server time instead of their local time, check out .info/serverTimeOffset in offline capabilities. (hint: you don't want to do that)
Note that when setting the timestamp on data that is saved to the server, using Firebase.ServerValue.TIMESTAMP is very appropriate.
Also see this fiddle for an example of manipulating date epochs into local Date objects.

dynamic highchart config in angular ui grid with angular js using pablojim's highcharts ng

my code (on the controller) to create an angular ui-grid -
function getData() {
$scope.myData = [];
$scope.columnDefs = [];
$scope.gridOptions = {
data: 'myData',
useExternalSorting: true,
columnDefs: 'columnDefs',
};
valuesService.getValues().success(function (data) {
$scope.columnDefs = getColumnDefs(data.DataColumns);
$scope.myData = data.Data;
if (!$scope.$$phase) $scope.$apply();
}).error(function (error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
}
function getColumnDefs(columns) {
var columnDefs = new Array();
for (var i = 0; i < columns.length; i++) {
columnDefs.push({
field: columns[i].Name,
displayName: columns[i].Caption,
width: columns[i].Width,
hasChart: columns[i].HasChart,
cellTemplate: "ui-grid-cell-template.html"
});
}
return columnDefs;
}
So in my controller i call the getData() function which will populate the grid with the gridOptions and create columnDefs array
As you see in the columnDefs i am using cellTemplate in the grid
And this is how my ui-grid-cell-template.html looks like -
<div ng-if="isChartColumn(col)"> //This works
<div class="ngCellText column-chart-style">
<highchart id="chart2"
config="{{getColumnChartConfig(col.colIndex())}}"></highchart> //this does not work
</div>
</div>
So my grid shows data columns and one of the column has a chart, which needs to read the config dynamically from controller's $scope object. This dynamic chart config object is to be supplied by getColumnChartConfig method on controller's scope which looks something like this in its simplest form -
//This function is not getting called
$scope.getColumnChartConfig = function (rowId) {
return someChartConfigObject;
}
Can you please let me know whether this is the correct way to accomplish what i am trying to and if it is then why is the getColumnChartConfig method not getting called from my grid's cellTemplate? Is there any other approach to do this?
Thanks in advance.
Don't use interpolation {{}} directive with config attribute And You inner div function should specifically point to the parent as you used ng-if, as it creates new child scope from current running scope. so you need to explicitly point to parent scope using $parent keyword
Markup
<highchart id="chart2" config="$parent.getColumnChartConfig(col.colIndex())">
</highchart>
I think you should be using appScope as well - refer http://ui-grid.info/docs/#/tutorial/305_appScope.
That would make your template more like:
<div ng-if="grid.appScope.isChartColumn(col)">
<div class="ngCellText column-chart-style">
<highchart id="chart2" config="grid.appScope.getColumnChartConfig(col.colIndex())}}">
</highchart>
</div>
</div>

How do I perform a 3-way binding with UI-Grid and Firebase?

I have an Angular UI grid filled with data that I pulled from Firebase. The grid table views perfectly with the $.asArray method with AngularFire, with the relevant code snippets as follows.
The Html View:
<!-- UI-Grid -->
<div ui-grid="gridOptions" class="ui-grid" ui-grid-resize-columns ui-grid-edit></div>
The Controller View:
var ref = new Firebase("https://commentme.firebaseio.com/comments");
// create an AngularFire reference to the data
var sync = $firebase(ref);
// create a synchronized array for use in our HTML code
$scope.comments = sync.$asArray();
$scope.newComment = {text: '', date: ''};
// pushes data back to Firebase Array
$scope.addComment = function(){
$scope.comments.$add($scope.newComment);
$scope.newComment = {text: '', date: ''};
// UI Grid Options
$scope.gridOptions = {
enableSorting: true,
columnDefs: [
{ name: 'comments', field: 'text'},
{ name: 'date', field: 'date'}
],
data: $scope.comments
};
The problem however is when I make edits to the UI-Grid (using the ui.grid.edit module) those changes only can reflect on my DOM and cannot persist/3-way bind back to the Firebase backend.
I tried binding the ng-model and ng-change using the editableCellTemplate within ColumnDefs with a code like this but still could not get it working.
editableCellTemplate: '<input type="text" ng-model="text" ng-change="comments.$save(text)">
Would appreciate if anyone could show me how to perform a 3-way bind with Firebase if I make changes to the cells of the UI-Grid table, thanks!
EDIT
Thanks to Kato's suggestions, I have finally made the binding between UI-Grid and Firebase! The solution is as follows.
The Html View:
<!-- UI-Grid -->
<div ui-grid="gridOptions" class="ui-grid" ui-grid-resize-columns ui-grid-edit ui-grid-row-edit ui-grid-cellNav></div>
The Controller View:
$scope.gridOptions.onRegisterApi = function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
};
$scope.saveRow = function( rowEntity ) {
//Firebase save and promise return
$scope.comments.$save(rowEntity).then(function(ref){
ref = $scope.comments;
});
// create a fake promise - normally you'd use the promise returned by $http or $resource
var promise = $q.defer();
$scope.gridApi.rowEdit.setSavePromise( $scope.gridApi.grid, rowEntity, promise.promise );
// fake a delay of 1 seconds whilst the save occurs, return error if item is empty
$interval( function() {
if (rowEntity === '' ){
promise.reject();
} else {
promise.resolve();
}
}, 1000, 1);
};
I have used a fake promise as I am not sure how to bind the returned promise from Firebase to the setSavePromise method. A promise is needed as UI-Grid will not allow you to re-edit the cells without the promise returned.
Your ng-change is attempting to save a single string as a record. You can't arbitrarily pass any value into $save; it must be a row index or the row itself.
Looking at the documentation for row editable, it looks like you can trigger an event each time a row "saves". I'd recommend giving that document a heavy poring over.
Something similar to this should do the trick, since the saveRow observable will return whatever data object exists in that spreadsheet row (i.e. the record from $asArray):
$scope.gridOptions.onRegisterApi = function(gridApi){
gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
};
$scope.saveRow = function(item) {
$scope.comments.$save(item);
};

Resources