Add a property to ng-grid column - angularjs

Using ng-grid, I'd like to add my own tooltip, using a header cell template. To do so I'd like to create a column property called "tooltip" for instance. Tried that and it doesn't show up in the col properties. What do you think about giving us that functionality. Otherwise I create a new template in each case?
See plunkr: http://plnkr.co/edit/lSf4XK?p=preview
Ideally, the gridOptions would contain columnDefs like this:
columnDefs: [
{field: 'complex.name', displayName: 'Name', headerCellTemplate:'header_template2.html'},
{field:'complex.active',
dimension1: "Testing",
displayName: 'In Progress',
headerCellTemplate:'header_template.html',
cellTemplate : 'checkBoxTemplate.html'}]
and that dimension1 property would be accessible in the template like so:
<div tooltip="{{col.dimension1}}">{{col.displayName}}</div>

Built a solution - more of a workaround - here:
http://plnkr.co/edit/0PMmrw?p=preview
Here's an excerpt. I make displayName an object instead of a string:
columnDefs: [
{field: 'complex.name', displayName: 'Name'},
{field:'complex.active',
cellClass: 'overflow-visible',
displayName: {name:'In Progress', tooltip:'Testing'},
headerCellTemplate:'header_template.html',
cellTemplate : 'checkBoxTemplate.html'}]
And then refer to it in the cell template like so:
<div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText" tooltip="{{col.displayName.tooltip}}">{{col.displayName.name}}</div>
Edit
The problem with this is that it will throw errors because the implementation of ng-grid expects displayName to be a string (at least in v2.0.7); it calls col.displayName.toLowerCase().

You can use cellClass/headerClass properties in my case i am not using cellClass for my columns so i used cellClass. I wanted attribute "help-id" on my each column header.
In your column definition:
{field: 'id.value', displayName: $scope.CONFIGVLANSlabels.tbl_vlans_id, enableCellEdit: true, editableCellTemplate: idEditCellTemplate, headerCellTemplate: myHeaderCellTemplate, cellClass:'tbl_vlans_id'}
In your header template
var myHeaderCellTemplate = '<div class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{cursor: col.cursor}" ng-class="{ ngSorted: !noSortVisible }">'+
'<div ng-click="col.sort($event)" ng-class="\'colt\' + col.index" class="ngHeaderText" help-id="{{col.cellClass}}">{{col.displayName}}</div>'+
'<div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>'+
'<div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>'+
'<div class="ngSortPriority">{{col.sortPriority}}</div>'+
'</div>'+
'<div ng-show="col.resizable" class="ngHeaderGrip" ng-click="col.gripClick($event)" ng-mousedown="col.gripOnMouseDown($event)"></div>';
Hope this will help some one.

(Cannot add a comment to the accepted answer due to rep score, so I'm adding it here)
An easy solution to get around the script errors of the accepted answer, a simple JavaScript object can be created to support the toLowerCase() call using in ng-grid:
function DisplayObject(name, tooltip) {
// this refers to the new instance
this.name = name;
this.tooltip = tooltip;
// you can also call methods
this.toLowerCase = function() {
return this.name.toLowerCase();
}
}
And then use it like this:
columnDefs: [
{field: 'complex.name', displayName: 'Name'},
{field:'complex.active',
cellClass: 'overflow-visible',
displayName: new DisplayObject('In Progress','Testing'),
headerCellTemplate:'header_template.html',
cellTemplate : 'checkBoxTemplate.html'}]
ng-grid will then no longer complain about the toLowerCase(), and the name will be added to the ng-grid fieldMap.

I'm using bootstrap 3.0, ui-bootstrap 0.10, nggrid 2.0.11, in order to make it works I define a header column template like the answer template, the difference is to use a tooltip-append-to-body="true" attribute for the tooltip. The cellClass: 'overflow-visible' in the column def is not neccesary.
<div class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{'cursor': col.cursor}" ng-class="{ 'ngSorted': !noSortVisible }">
<div ng-click="col.sort($event)" ng-class="'colt' + col.index" class="ngHeaderText" tooltip-append-to-body="true" tooltip="{{col.displayName.tooltip}}">{{col.displayName.name}}</div>
<div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>
<div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>
<div class="ngSortPriority">{{col.sortPriority}}</div>
<div ng-class="{ ngPinnedIcon: col.pinned, ngUnPinnedIcon: !col.pinned }" ng-click="togglePin(col)" ng-show="col.pinnable"></div>
</div>
<div ng-show="col.resizable" class="ngHeaderGrip" ng-click="col.gripClick($event)" ng-mousedown="col.gripOnMouseDown($event)"></div>

Related

Handling angularjs ui grid cell template ng-click function for var ctrl = this syntax in the controller

I have the following columnDefs for my angularjs ui grid :
ctrl.temporaryRegGridOptions.columnDefs = [ {
field: 'firstName',
'displayName': 'First / Company Name',
cellTemplate: '<span ng-click="ctrl.grid.appScope.gotoRequiredState()">{{row.entity.firstName}} </span> '
}, {
field: 'lastName',
'displayName': 'Surname',
width: '150'
} ]
and I have
ctrl.gotoRequiredState = function() {
alert("next State");
}
All I need to do is, on ng-click of a cell I need to call a function.Similar to ClicMe at http://ui-grid.info/docs/#/tutorial/305_appScope. On the official website this feature is given with $scope but in my controller, I am using var ctrl = this; syntax. May be that is the reason even if I have given ng-click="grid.appScope.gotoRequiredState()">, the gotoRequiredState() function is not getting called. So I have changed it to ng-click="ctrl.grid.appScope.gotoRequiredState()"> but still no luck. Even after I click firstName cell, the gotoRequiredState() function is not getting called. Can any one help me to fix this.
The following has solved the problem :
ctrl.temporaryRegGridOptions.appScopeProvider = ctrl;
with
cellTemplate: '<span ng-click="grid.appScope.gotoRequiredState()">{{row.entity.firstName}} </span> '
works fine.
otherwise simply using :
cellTemplate: '<span ng-click="grid.appScope.$parent.$ctrl.gotoRequiredState()">{{row.entity.firstName}} </span> '
works fine without assigning ctrl to appScopeProvider. By the way I am using Angularjs 1.5 + components architecture.
From the documentation that you have shared, I presume that appScope is the parent scope of the grid directive.
If thats the case, could you try
ng-click="grid.appScope.ctrl.gotoRequiredState()" ?

I want to write a custom directive for ui-grid with different input columnDefs

This is my Controller
$scope.usersList = {};
$scope.usersList = {
paginationPageSizes: [10,15, 20],
paginationPageSize: 10,
columnDefs: [
{ name: 'userId', cellTemplate: '<div class="ui-grid-cell-contents"><a ui-sref="appSetting.userSelected({userId: row.entity.userId})">{{ row.entity.userId }}</a></div>' },
{ name: 'firstName' },
{ name: 'lastName' },
{ name: 'emailId' },
{
name: 'action',
cellTemplate: '<div>' +
' <button ng-click="grid.appScope.sampledetails()">Delete</button>' +
'</div>',
enableSorting: false,
enableColumnMenu: false
}
]
};
and this is my .cshtml
<div id="grid1" ui-grid="gridOptions" class="grid"></div>
I want to write this in such a way that it should be used in other .cshmtls, but the columnDefs varies depending on table column name. How should I write in such a way that ths user should give the columnsDefs in directive along with pagination?
Your question is hard to understand, hopefully I got it right. You want to define default-settings for your grid but enable the user to input some special settings if needed?
Warp ui-grid in your own directive. Pass your wanted arguments into that directive and create default settings in your directive.
Your .cshtml. You pass your settings variable into that.
<my-grid options="usersList" />
Your Directive. Grab the settings there (see options: '=') and bind that to controller or scope.
angular.module('app').directive('myGrid', myGrid);
function myGrid() {
return {
templateUrl : 'grid.html',
controller : 'GridCtrl',
controllerAs : 'grid',
restrict: 'E',
scope: {
options : '=',
},
bindToController: true,
};
}
Your Controller. Now you can access your settings in that controller.
There you could combine the default settings with your inserted settings and pass that into the directive template.
angular.module('app').controller('GridCtrl', GridCtrl);
function GridCtrl() {
var grid = this;
console.log(grid.options); // containts your settings
grid.gridOptions = {
paginationPageSize: grid.options.paginationPageSize,
...,
columnDefs: grid.options.columnDefs
etc
}
}
And your grid.html, you pass the combined settings into the grid-API.
<div id="grid1" ui-grid="grid.gridOptions" class="grid"></div>
There are many more details to watch out for, but thats a possible setup.
e: I made a Plunkr for another similar question. For future reference.

Alternate row colours in ExtJS view.View

I have an ExtJS 4.2 view.View (dataView) using a template, store and model; pretty much as the documentation describes, and the information is displayed fine.
I now need to alternate the background colour of each item. How is this best accomplished?
There aren't any easy config options to do this like Sencha Touch's striped: true, or any inherent styling like in the grid.Panel; I have looked for a listener that would allow for setting the tpl and itemSelector for each item, but there doesn't seem to be anything listed that would suffice.
Code:
Ext.define('productionHistoryModel', {
extend: 'Ext.data.Model',
fields: [ 'Date', 'Fore_Name', 'Event', 'Comments' ]
});
var productionHistoryStore = Ext.create('Ext.data.Store', {
id: 'productionHistoryStore',
storeId: 'productionHistoryStore',
model: 'productionHistoryModel'
});
var historyTpl1 = new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="x-grid-row">',
'<span style="font-weight: bold;">{Date}: {Event} ({Fore_Name})</span>',
'<br/><span>{Comments}</span>',
'</div>',
'</tpl>'
);
var productionHistoryView = Ext.create('Ext.view.View', {
id: 'productionHistoryView',
store: productionHistoryStore,
tpl: historyTpl1,
itemSelector: 'div.x-grid-row',
emptyText: 'No logs available',
disableSelection: true,
autoScroll: true,
maxHeight: 500
});
You're using a view which means you're defining the HTML to be generated yourself, using a XTemplate. That is why there is no built-in feature for striped rows, since the framework simply doesn't know which HTML will be rendered.
The simplest solution is to add a class attribute to each row in your template indicating whether the row number is odd or even, and then use CSS to style the rows accordingly.
Actually there already is an example in the documentation of Ext.XTemplate (scroll down to "Execute arbitrary inline code with special built-in template variables"):
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
'<p>Kids: ',
'<tpl for="kids">',
'<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
'{name}',
'</div>',
'</tpl></p>'
);
The corresponding CSS code would look like:
.odd {
background-color: white;
}
.even {
background-color: gray;
}

Dynamic enableCellEdit

I am trying to figure out how to dynamically set enableCellEdit on a cell based on information in the row. For example, something like:
$scope.gridOpts = {
data: 'mydata',
columnDefs: [{field: 'sometimesIEdit', enableCellEdit:row.isEditable}]
}
Clearly row is not available in this context. Maybe enableCellEdit is evaluated purely at the column level and not the cell level making what I want to do impossible - I'm not sure.
I know that as a work around I can use editableCellTemplate with ng-if to show plain text, but I would rather the cell never go editable at all.
For me, the only solution that worked is using cellEditableCondition as a function:
cellEditableCondition: function ($scope) { return $scope.row.entity.isEditable }
This is pretty old but figured I'd attempt to answer anyway. I had this exact same problem and solved it using the editableCellTemplate for that column. This is the template I used is something like this:
var editableCellTemplate = '<div class="email" ng-edit-cell-if="isFocused && '
+ 'row.entity.canEdit">'
+ '<input ng-class="\'colt\' + col.index" ng-input="COL_FIELD" '
+ 'ng-model="COL_FIELD" />'
+ '</div>'
+ '<div ng-edit-cell-if="isFocused">'
+ '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>'
+ '{{COL_FIELD}}</span></div>'
+ '</div>'
+ '</div>';
So only if the row entity has canEdit equal to true can that cell be edited.
Another solution is to decorate one of ng-grid`s directives.
In this case 'ngCellHasFocusDirective'.
The basic logic is preventing event`s from firing if a condition is not met.
Using this method you can control cell edit for a cell when another cell in the row was changed.
I`m note sure if the "CellTemplate" solution will work when another cell in the row is edited and the result of this edit should disable cell editing for another cell in the row.
This is because a cell change activate a $digest on the cell $scope, I dont believe the $digest is fired on the row $scope.
In this gist link below I wrote a decorator for the 'ngCellHasFocus' directive which fires a function defined in "columnDef', the function returns TRUE or FALSE, editable or not.
An exapmle included.
GIST: https://gist.github.com/shlomiassaf/7485c61ecb464f261194
Old question, but as we need to maintain an app still using ng-grid (>=2.0.9), I thought I'd answer.
As it says in the docs (https://github.com/angular-ui/ui-grid/wiki/Defining-columns), you may specify a cellEditableCondition: boolean, either on the columnDef or in the Options object.
It also requires enableCellEdit: 'expression'.
Example is extracted from the link above
$scope.gridOptions = {
data: myDataSource,
enableCellSelection: true,
enableCellEditOnFocus: true,
cellEditableCondition: 'row.entity.editable',
columnDefs: [
{ field: 'firstName', displayName: 'First Name', width: "*", resizable: false, enableCellEdit: false},
{ field: 'lastName', displayName: 'First Name', width: "20%"},
{ field: 'address', displayName: 'Last Name', width: "*" ,
cellEditableCondition: 'row.entity.editable && !row.entity.isAddressDefined()'},
{ field: 'age', cellClass: 'ageCell', headerCellClass: 'ageHeader', width: "**"}]
};

Using ng-switch in angularjs directive and using that directive in ng-grid cellTemplate

I made a following directive:
.directive('getData', function(){
return {
restrict: 'C',
replace: true,
transclude: true,
scope: { myData:'#myData' },
template: '<div ng-switch="myData">' +
'<div ng-switch-when="4">Real Data</div>' +
'<div ng-switch-when="5">False Data</div>' +
'<div ng-switch-default>No Data</div>' +
'</div>'
}
Then on a grid that uses ng-grid, I have a column that has 2 rows with values 4 and 5. I have following in cellTemplate for this column:
cellTemplate: ' < div class="getData" myData="{{row.getProperty(col.field)}}" />'
The problem is both the rows display "No Data". I would like to show "Real Data" on the cell that has value 4 and "False Data" on the cell that has 5.
What I am not doing right? Any help would be greatly appreciated.
In your cellTemplate change myData to my-data. When using angular directives camel case is converted to dash case automatically by the angular library.
For example if you have a directive element defined as "mySuperAwesomeDirective". It would be declared in html using the following.
<my-super-awesome-directive></my-super-awesome-directive>
Here is a working version of your plunker example.
http://plnkr.co/edit/ENj00Re3bfaVGPlomhFG?p=preview

Resources