Angularjs grid is an open source data grid for angularjs(1+) framework which can be used for free in open source and commercial applications.
If you are looking for Angular (2 < version < 7) grid, then check out Angular section in ParamQuery Demos
Angularjs grid uses ParamQuery grid
( written in javascript/jQuery ) under the hood and is encapsulated in a directive for seamless
integration with angularjs framework.
For you as a developer, jQuery knowledge is optional and is not necessary for implementation of angularjs grid.
User interface regions of the grid like toolbar, grid body cells, header cells, row details, nested grids, editors, validations, etc feature two way data angularjs bindings i.e., any change in the model variables update the UI and any UI updates by the user update the model variables. The events in the grid can also be bound to controller methods through attributes.
First of all include the additional dependencies in this order ( after the files mentioned in the include files section for ParamQuery grid):
angular.min.js
which can be downloaded from https://angularjs.org
or point it to CDN: http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js
ng.pqgrid.min.js
which contains the module and directive of pqgrid for Angularjs.
Add the pq.grid
module to our main module.
angular.module('myApp', ['pq.grid'])
Define the grid options as model properties by adding it to $scope variable in our controller.
controller('myCtrl', function($scope){ $scope.gridModel = { width: "80%", height: 400, ... }; });
We pass on the gridModel as options attribute to pq-grid
directive in our HTML view.
<div ng-controller="myCtrl"> ... <pq-grid options="gridModel" ></pq-grid> ... </div>
grid instance is used to call API of the grid in order to manipulate it.
i.e., grid.sort( params.. )
When grid is being initialized, grid instance is added to gridModel as its property i.e.,
gridModel.grid
.
When grid is initialized, grid gets a new scope prototypically inherited from its parent scope.
grid instance is added as a property to grid scope as $scope.grid
which implies that it can be accessed from any bindings or directives which use the grid scope or have
child scopes protypically inherited from grid's scope.
Conversely, the scope of the grid can be obtained from grid instance as grid.$scope
which is convenient to access or manipulate grid scope inside grid event handlers.
Dot notation or defining model variables as properties of objects is recommended over adding them directly to $scope to avoid
problems with setting model variable values from child scopes that prototypically inherit from parent scopes.
controllerAs
offers a much cleaner solution by offering this
variable inside the controller
so that the model variables can be declared as properties of this
variable.
Controller:
controller('myCtrl', function(){ var vm = this; vm.gridModel = { width: "80%", height: 400, ... }; });
View:
<div ng-controller="myCtrl as vm"> ... <pq-grid options="vm.gridModel" ></pq-grid> ... </div>
For toolbar binding, we set gridModel.ngModel.compileToolbar = true
and add angularjs directives or expressions in gridModel.toolbar.items[].type
or gridModel.toolbar.items[].attr
properties.
Toolbar gets the grid scope.
ngModel: {compileToolbar: true}, toolbar: { items: [ { type: 'select', label: 'Select number of frozen rows: ', attr: 'ng-model="vm.gridModel.freezeRows" ng-options="o as o for o in vm.options"' }, { type: 'separator' }, { type: 'checkbox', label: 'Exclude frozen rows while sorting', attr: 'ng-model="vm.sortAll"' } ] }
Every row in grid gets a new scope prototypically derived from the grid scope when either
gridModel.ngModel.compileRows = true
or there is a template property in any of the columns.
The row scope has properties:
rd
which is reference to the rowData of current row.ri
rowIndx of current row which is similar to $index in ng-repeat.column.template
property.
e.g.,
{ title: "Company", dataIndx: "company", template: '<span ng-class="ri%2==0?\'bold_cls\':\'\'">{{rd.company}}</span>' }
If we need column specific properties in the cell templates, then we use render callback
and return template which has access to column specific properties e.g., colIndx, column, dataIndx
through ui argument inside the render callback.
Note that it's required to add compileRows: true
to ngModel in this case.
{ title: "", align: 'center', editable: false, render: function( ui ){ var width = ui.column.outerWidth, ci = ui.colIndx return '<button class="btn-primary btn" ng-click="vm.showMe(ri,rd,'+width+','+ci+')">Click Me</button>'; } }
Header of the grid is compiled with grid scope when
gridModel.ngModel.compileHeader = true
.
For header cells binding, we add angularjs expressions in column.title
property.
e.g.,
{ title: "No of clicks: {{vm.ri}}", dataIndx: "company" }
If we need column specific properties, then we use callback variant
of column.title
which has access to column specific properties e.g., colIndx, column, dataIndx
through ui argument.
{ align: 'center', editable: false, dataIndx: 'rank', sortable: false, title: function( ui ){ return '<button class="btn-primary btn" ng-click="vm.showMe('+ui.column.outerWidth+')">Click Me</button>'; } },
Events of the grid can be subscribed to in 2 ways:
Add inline event handlers as property of gridModel e.g.,
//inline property of gridModel. beforeSort: function( evt, ui ){ }
The context this
in this case is grid
which emits the event.
Specify event handler as attribute in directive and add event handler method in the controller e.g., to listen to beforeSort event.
<!--Note: the event attribute name starts with on- and put in lower case separated by hyphens --> <pq-grid on-before-sort="vm.beforeSort(evt, ui, grid)" options="vm.gridModel" ></pq-grid>
//add event handler in the controller. vm.beforeSort = function( evt, ui, grid ){ }
The context this
in this case is controller. So to get access to grid that emits the event, we can pass grid as one
of the parameters to the event. This way of event binding also ensures that at least one $root $digest
takes place
after call to event handler.
Two way data binding of the whole data in grid can be obtained by:
Assign data to an object property inside the controller i.e.,
vm.myData = data;
where vm is an object defined on the $scope or vm points to this
variable inside the controller
when used with controllerAs
syntax.
Assign model property name along with object name in dot notation as a string e.g., 'vm.myData'
to
gridModel.dataModel.data
.
gridModel.dataModel = { data: 'vm.myData' };
When gridModel properties change after initialization of grid, rebind
attribute indicates grid to observe for those changes
and refresh view according to the changes.
rebind is passed to grid directive as an attribute whose value is the name of a single or more options ( separated
by empty space in latter case ) whose values are observed by the grid during every $digest
.
Note that it is supported only for scalar properties currently.
<pq-grid rebind="height selectionModel.type"></pq-grid>
rebind has special value all
which indicate that the grid should observe all scalar properties of the gridModel.
<pq-grid rebind="all"></pq-grid>
Custom editors are implemented by writing a directive and assigning it to column.editorTemplate
Directives are assigned a scope prototypically derived from grid scope and has following properties.
ui:
An object having same ui properties received in callbacks of column.editor
angular.module('pq.grid') .directive('autocomplete', function(){ return{ restrict: 'AE', link: function($scope, $ele, attr){ debugger; var ui = $scope.ui, $cell = ui.$cell, rowData = ui.rowData, dataIndx = ui.dataIndx, width = ui.column.width, cls = ui.cls, dc = $.trim(rowData[dataIndx]); var $inp = $("<input type='text' name='" + dataIndx + "' class='" + cls + " pq-ac-editor' />") .width(width - 6) .appendTo($cell) .val(dc); $inp.autocomplete({ source: attr.options? $scope.$eval(attr.options): attr.url, minLength: 0 }).focus(function () { //open the autocomplete upon focus $(this).autocomplete("search", ""); }); } }; })
Custom validations are implemented by writing a directive and assigning it to column.validations[].template
Directives are assigned a scope prototypically derived from grid scope and has following properties.
ui:
An object having same ui properties received by callback in column.validations[]
angular.module('pq.grid') //validation directives. .directive('inList',function(){ return{ restrict: 'E', link: function($scope, $ele, $attr){ var ui = $scope.ui, value = ui.value, list = $scope.$eval($attr.options); if ( list.indexOf( value ) == -1) { ui.msg = value + " not found in list"; $scope.return = false; } } }; })
Row details are implemented by writing a directive and assigning it to detailTemplate
.
Directive is assigned a scope prototypically derived from grid scope and has following properties.
ui:
An object having same ui properties received by detailModel.init callback.
angular.module('pq.grid') .directive('pqGridDetail', ["$compile", function($compile){ function link($scope, $ele){ $scope.rd = $scope.ui.rowData; $ele = $compile( $ele )( $scope ); //link should return the compiled $ele. return $ele; } return{ template: function($ele, attr){ //template requires one root element. return "<div>" + $("#"+attr.templateId).html() + "</div>"; }, terminal: true, restrict: 'AE', replace: true, link: link }; }]);
Copyright @ 2016-2022 Paramvir Dhindsa (http://paramquery.com)