How to load dynamic column and rows by Using ag-grid? - javascript

Html Code :
<div class="panel-body" style="padding-bottom:0px">
<div id="myGrid" ag-grid="gridOptions" class="ag-fresh" style="height: 100%;"></div>
</div>
Angular Code :
var sqdtApp = angular.module("sqdtApp", ['ngTouch',
'ui.grid', 'ui.grid.pagination', 'ui.grid.resizeColumns',
'angularUtils.directives.dirPagination', 'ngAnimate', 'ui.bootstrap', 'agGrid']);
sqdtApp.controller(
'importedtableCtrl',
function ($http, $scope, $stateParams,$rootScope, $httpParamSerializer, uiGridConstants) {
$scope.dbtype = $stateParams.dbname;
$scope.columns = [];
$scope.gridOptions = {
columnDefs: [],
enableFilter: true,
rowData: [],
rowSelection: 'multiple',
rowDeselection: true
};
$scope.customColumns = [];
$http.post($scope.url + "/importedtablesCount", { 'dbname': $stateParams.dbname })
.success(
function (result) {
$scope.importedTableCount = result;
});
var gridtablename = "";
$scope.currentImportedTableName = '';
$scope.loadTableInGrid = function (tablename) {
$scope.currentImportedTableName = tablename;
if (gridtablename != tablename) {
$scope.reset();
gridpageno = 1;
$http.post($scope.url + "/getPagingRecordImportedTable", { 'dbname': $stateParams.dbname, 'tableName': tablename, 'pageNumber': 1 }).success(
function (response) {
$scope.names = response.records;
$scope.mdata = response.metadata;
// $scope.gridOptions.data = response.records;
var columnsize = 0;
console.log($scope.customColumns);
for (var obj in $scope.mdata) {
if ($scope.mdata[obj]['columnsize'] > 20) {
columnsize = 20;
} else {
columnsize = $scope.mdata[obj]['columnsize'];
}
$scope.customColumns.push({
headerName: $scope.mdata[obj]['columnname'],
field: $scope.mdata[obj]['columnname'],
headerClass: 'grid-halign-left'
});
}
$scope.gridOptions.columnDefs = $scope.customColumns;
$scope.gridOptions.rowData = $scope.names;
gridtablename = tablename;
gridpageno = 1;
$scope.getTotalNoOfRecordCountForGrid(tablename);
}).error(function (data) {
alert(data);
});
} else {
$scope.reset();
$scope.resetGridTableName();
}
};
});
Output No Rows to Show
no rows to show is output
but if i check in $scope.gridoptions object all the rows and column are there.
$scope.gridOptions object in console with data
but it not rendering in page.
help me out.

$scope.gridOptions.columnDefs = $scope.customColumns;
$scope.gridOptions.rowData = $scope.names;
Those are very likely the culprits : columnsDefs and rowData are only for grid initialisation before the ready event.
Use gridOptions.api.setColumnDefs and gridOptions.api.setRowData to interact with the grid once it's initialized
Documentation : https://www.ag-grid.com/angular-grid-api/index.php

Related

Angular Modal Service unknown provider

I am trying to get a angular modal form working but I am always getting an unknown provider error. I think I have included all the necessary files?
Here is my code for calling the service:
function deleteConfirm() {
var modalOptions = {
closeButtonText: 'Cancel',
actionButtonText: 'Delete Supplier',
headerText: 'Delete ' + supplierName + '?',
bodyText: 'Are you sure you want to delete this supplier?'
};
modalService.showModal({}, modalOptions).then(function(result) {
if (result === 'ok') {
alert("ok");
}
}, function(error) {
alert("Error deleting");
});
}
And here is the code for the service:
(function() {
'use strict';
modalService.$inject = '$uibModal';
angular.module('plunker').factory('modalService', modalService);
function modalService($uibModal) {
var injectParams = ['$uibModal'];
//var modalService = function($uibModal) {
var modalDefaults = {
backdrop: true,
keyboard: true,
modalFade: true,
templateUrl: 'modal.html'
};
var modalOptions = {
closeButtonText: 'Close',
actionButtonText: 'OK',
headerText: 'Proceed?',
bodyText: 'Perform this action?'
};
this.showModal = function(customModalDefaults, customModalOptions) {
if (!customModalDefaults) customModalDefaults = {};
customModalDefaults.backdrop = 'static';
return this.show(customModalDefaults, customModalOptions);
};
this.show = function(customModalDefaults, customModalOptions) {
//Create temp objects to work with since we're in a singleton service
var tempModalDefaults = {};
var tempModalOptions = {};
//Map angular-ui modal custom defaults to modal defaults defined in this service
angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
//Map modal.html $scope custom properties to defaults defined in this service
angular.extend(tempModalOptions, modalOptions, customModalOptions);
if (!tempModalDefaults.controller) {
tempModalDefaults.controller = function($scope, $uibModalInstance) {
$scope.modalOptions = tempModalOptions;
$scope.modalOptions.ok = function(result) {
$uibModalInstance.close('ok');
};
$scope.modalOptions.close = function(result) {
$uibModalInstance.close('cancel');
};
};
tempModalDefaults.controller.$inject = ['$scope', '$uibModalInstance'];
}
return $uibModal.open(tempModalDefaults).result;
};
}
}());
http://plnkr.co/edit/xNpbI42UJm8acODSOimR
Thanks for any help
angular.module('plunker').factory('modalService', modalService);
modalService.$inject = ['$uibModal'];
Try this!
Add to main app.js dependencies ['ui.bootstrap']
var app = angular.module('plunker', ['ui.bootstrap']);
You forgot to include "ui.bootstrap" into your app.
Simply bootstrap your app like this to correct the issue :
var app = angular.module('plunker', ["ui.bootstrap"]);

Why am I getting "Incorrect injection token!" in this angular application code?

I'm trying to setup a restful API interface via AngularJS with the following code:
'use strict';
(function(angular) {
function ApiAction($resource, ResourceParameters) {
return $resource(ResourceParameters.route,
{ },
{ api_index: {
method: ResourceParameters.method,
isArray: true
}
});
return $resource(ResourceParameters.route,
{ },
{ create: {
method: ResourceParameters.method,
isArray: true
}
}
);
}
function ResourceParameters($scope) {
var factory = {};
factory.method = '';
factory.route = '';
factory.SetMethod = function(method) {
factory.method = method;
}
factory.SetRoute = function(route) {
factory.route = route;
}
return factory;
}
function superheroCtr($scope, ApiAction, ResourceParameters) {
$scope.superheroSubmit = function() {
// ApiAction.create({}, { superhero_name: $scope.superheroName, age: $scope.superheroAge });
angular.forEach($scope.superheroes, function(hero) {
// ApiAction.create({}, { superhero_name: hero.superhero_name, age: hero.age });
});
};
var heroesResources = ResourceParameters($scope).SetRoute('/api/');
var heroes = ApiAction.api_index({}, heroesResources);
$scope.superheroes = [];
heroes.$promise.then(function(data) {
angular.forEach(data, function(item) {
$scope.superheroes.push(item);
});
}, function(data) {
//if error then...
});
$scope.appendSuperheroFields = function() {
var i = $scope.superheroes.length + 1;
$scope.superheroes.push({"id": i, age: "", superhero_name: "" })
}
}
var superheroApp = angular.module('superheroApp', ['ngResource']);
superheroApp.controller('superheroCtr', ['$scope', 'ApiAction', 'ResourceParameters', superheroCtr]);
superheroApp.factory('ResourceParameters', ['$scope', ResourceParameters]);
superheroApp.factory('ApiAction', ['$resource', ResourceParameters, ApiAction]);
})(angular);
Yet, when I run it I get the following error:
Error: [$injector:itkn] Incorrect injection token! Expected service name as string, got function ResourceParameters($scope)
Why is this?
Simply you can not inject $scope OR you can not have access to $scope
inside a factory
Your problem is at this line
superheroApp.factory('ResourceParameters', ['$scope', ResourceParameters]);
You need to replace that line with
superheroApp.factory('ResourceParameters', [ResourceParameters]);
Factory
function ResourceParameters() { //<--removed $scope from here
var factory = {};
factory.method = '';
factory.route = '';
factory.SetMethod = function(method) {
factory.method = method;
}
factory.SetRoute = function(route) {
factory.route = route;
}
return factory;
}
Update
Additionally you should correct the declaration of ApiAction where ResourceParameters should be placed inside ' single qoutes
superheroApp.factory('ApiAction', ['$resource', 'ResourceParameters', ApiAction]);

angularjs restricting count to current scope

I am tring to setup a counter where for each country in my list I can keep count of how many clicks there has been plus an overall tally.
I have the below so far which can be viewd in this fiddle. The issue I am having is that I am not able to keep the count unique for each country. How can this be achieved?
<div ng-app="myApp">
<div data-ng-view></div>
</div>
'use strict';
var myApp = angular.module('myApp', ['ngRoute', 'templates/view1.html', 'templates/view2.html']);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'templates/view1.html',
controller: 'CountryListCtrl'
})
.when('/:id', {
templateUrl: 'templates/view2.html',
controller: 'CountryCtrl'
})
}]);
myApp.factory('Countries', ['$q', function ($q) {
var countriesList = [];
// perform the ajax call (this is a mock)
var getCountriesList = function () {
// Mock return json
var contriesListMock = [
{
"id": "0",
"name": "portugal",
"abbrev": "pt"
}, {
"id": "1",
"name": "spain",
"abbrev": "esp"
}, {
"id": "2",
"name": "angola",
"abbrev": "an"
}
];
var deferred = $q.defer();
if (countriesList.length == 0) {
setTimeout(function () {
deferred.resolve(contriesListMock, 200, '');
countriesList = contriesListMock;
}, 1000);
} else {
deferred.resolve(countriesList, 200, '');
}
return deferred.promise;
}
var getCountry = function(id) {
var deferred = $q.defer();
if (countriesList.length == 0) {
getCountriesList().then(
function() {
deferred.resolve(countriesList[id], 200, '');
},
function() {
deferred.reject('failed to load countries', 400, '');
}
);
} else {
deferred.resolve(countriesList[id], 200, '');
}
return deferred.promise;
}
var cnt = 0;
var cntryCnt = 0;
var incCount = function() {
cnt++;
return cnt;
}
var incCntryCount = function(id) {
cntryCnt++;
return cntryCnt;
}
return {
getList: getCountriesList,
getCountry: getCountry,
getCount : function () {
return cnt;
},
getCntryCount : function () {
return cntryCnt;
},
incCount: incCount,
incCntryCount: incCntryCount
};
}]);
myApp.controller('CountryListCtrl', ['$scope', 'Countries', function ($scope, Countries) {
$scope.title = '';
$scope.countries = [];
$scope.status = '';
Countries.getList().then(
function (data, status, headers) { //success
$scope.countries = data;
},
function (data, status, headers) { //error
$scope.status = 'Unable to load data:';
}
);
}]);
myApp.controller('CountryCtrl', ['$scope', '$routeParams', 'Countries', function ($scope, $routeParams, Countries) {
$scope.country = {
id: '',
name: '',
abbrev: ''
};
var id = $routeParams.id;
Countries.getCountry(id).then(
function(data, status, hd) {
console.log(data);
$scope.country = data;
$scope.countOverall = Countries.getCount;
$scope.countCntry = Countries.getCntryCount;
$scope.clickCnt = function () {
$scope.countTotal = Countries.incCount();
$scope.country.clicks = Countries.incCntryCount(id);
console.log($scope);
};
},
function(data, status, hd) {
console.log(data);
}
);
}]);
angular.module('templates/view1.html', []).run(["$templateCache", function ($templateCache) {
var tpl = '<h1>{{ title }}</h1><ul><li ng-repeat="country in countries"><a href="#{{country.id}}">{{country.name}}</div></li></ul>';
$templateCache.put('templates/view1.html', tpl);
}]);
angular.module('templates/view2.html', []).run(["$templateCache", function ($templateCache) {
var tpl = '<div>{{country.name}} clicks {{countCntry()}} <br> overall clicks {{countOverall()}}</div><button>BACK</button><button ng-click="clickCnt()" >count clicks ++ </button>';
$templateCache.put('templates/view2.html', tpl);
}]);
The problem is that you are not incrementing a count based on the country. Working on the fiddle right now.
EDIT:
I've updated the fiddle: http://jsfiddle.net/1xtc0zhu/2/
What I basically did was making the cntryCnt an object literal which takes the country id as a property and keeps the right counting per each id, like so:'
var cnt = 0;
var cntryCnt = {};
...
// The function now receives the country id and increments the specific country clicks only.
var incCntryCount = function(id) {
cntryCnt[id] = cntryCnt[id] || 0;
cntryCnt[id]++;
return cntryCnt[id];
}
The rest of the changes are in the templates, and are basically only sending the country id as a param when getting or incrementing the counts.
Also, this is not an Angular Specific question, but more a programming in general question.

Calling a function from Angular.js Controller

Following is a simple Angular.js code snippet :
XApp.controller('ProductsController', function ($scope, GetProductsForIndex, $http) {
console.log('Step 1');
var Obj = new Object();
Obj.PAGEINDEX = 1;
Obj.PAGESIZE = 25;
Obj.SPNAME = "index_get_products";
Obj.PAGECOUNT = null;
Obj.COUNTRYCODE = 'in'
$scope.data = GetProductsForIndex.query({ parameters : Obj }, function () {
console.log($scope.data);
$scope.products = $scope.data;
});
})
XApp.factory('GetProductsForIndex', function ($resource) {
console.log('Step 2');
return $resource('api/index/:object?type=json', {}, { 'query': { method: 'GET', isArray: true } });
});
I am trying to implement infinite scroll using http://binarymuse.github.io/ngInfiniteScroll/
In their demo here http://binarymuse.github.io/ngInfiniteScroll/demo_basic.html they are calling the loadMore() function.
In my case i want to execute the following on scroll :
$scope.data = GetProductsForIndex.query({ parameters : Obj }, function () {
console.log($scope.data);
$scope.products = $scope.data;
});
and increment the pageIndex Obj.PAGEINDEX = 1 by 1. How am i supposed to do that? Today is my 3rd day with Angular.js.
You need to implement a loadMore function like this inside your controller ,
XApp.controller('ProductsController', function ($scope, GetProductsForIndex, $http) {
function loadData($scope, obj){
$scope.products.push( GetProductsForIndex.query({ parameters : Obj }, function () {
}));
}
console.log('Step 1');
var Obj = new Object();
$scope.products=[];
Obj.PAGEINDEX = 1;
Obj.PAGESIZE = 25;
Obj.SPNAME = "index_get_products";
Obj.PAGECOUNT = null;
Obj.COUNTRYCODE = 'in'
loadData($scope, Obj);
})

Organizing a AngularJS Controller

I'm new to the AngularJS world and come from a Backbone background. So far I'm loving it but there is quite a big difference in terms of architecture practices between the two ( someone should write an article on this lol ).
I'm starting to structure some quite large controllers and it just doesn't feel right. For instance, this is a basic control that deals with executing a search and populating the ng-grid control and infinite scrolling this grid.
var ctrl = ['$scope', 'model', '$modal', function ($scope, model, $modal) {
$scope.page = 0;
$scope.loading = true;
$scope.mySelections = [];
$scope.rows = [];
$scope.columnDefs = [{
field: 'Checked',
width: "50",
sortable: false,
headerCellTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-show="multiSelect" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
cellTemplate: '<div class="ngSelectionCell"><input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" /></div>'
}];
$scope.gridOptions = {
data: 'rows',
columnDefs: "columnDefs",
enableColumnResize: true,
selectedItems: $scope.mySelections,
};
/**
* Pages the grid and returns a $.deferred
*/
var pageGrid = function () {
return model.ExecuteSearchForReport("4146", ++$scope.page)
.done(function (records) {
$.each(records, function (i, record) {
var fields = {};
$.each(record.Value, function (ii, field) {
var fieldKey = field.Key.replace(/\s/g, '');
fields[fieldKey] = field.Value;
});
$scope.rows.push(fields)
});
$scope.$digest();
});
};
/**
* Page the grid initally.
*/
pageGrid().done(function (records) {
createColumns(records);
$scope.loading = false;
// if the grid height
var gridHeight = $('.ngGrid').height();
var repage = function () {
if ($('.ngCanvas').height() < gridHeight) {
pageGrid().done(function () {
repage();
});
}
};
repage();
$scope.$digest();
});
/**
* Creates the columns for the grid based on the records.
*/
var createColumns = function (records) {
if (records.length) {
$.each(records[0].Value, function (ii, field) {
var fieldKey = field.Key.replace(/\s/g, '');
var col = {
field: fieldKey,
displayName: field.Key,
resizable: true
};
// all the other columns are small
if (fieldKey !== "FileName") {
col.width = "100";
}
$scope.columnDefs.push(col);
});
}
};
/**
* List for `ngGridEventScroll` event to page the data set.
*/
$scope.$on('ngGridEventScroll', function () {
pageGrid();
});
/**
* Move the secure button was clicked, load next screen.
*/
$scope.moveToSecure = function () {
$scope.loading = true;
model.GetSecureDetails().done(function (data) {
$scope.loading = false;
var modalInstance = $modal.open({
templateUrl: 'Views/Modal.html',
controller: ModalInstanceCtrl,
resolve: {
data: function(){
return {
header: "Move To Secure",
body: "Views/Move.html",
lists: data
};
}
}
});
modalInstance.result.then(function (formData) {
var defs = [];
$.each($scope.mySelections, function (i, sel) {
defs.push(model.MoveToSecure({
Id: sel.EventID.substring(4, sel.EventID.length),
Filename: sel.FileName
}));
});
$.when.apply($, defs).done(function () {
alert('Move completed');
});
});
});
};
}];
I know, its a lot and it feels unstructured somewhat to me, between all the variable initialization, private methods, and general initialization methods. It doesn't feel concise and deterministic to me, which is something I liked about Backbone. Anyone got any feedback on a better way to do this? Thanks!
You need to move most of that stuff into 'concise' directives. If you don't master directives, your controllers will always end up overburdened and crazy like this. Ideally your controller pretty much only takes data back and forth between your scope and services.

Categories

Resources