Skip to content

Commit 739e578

Browse files
authored
Merge pull request #5611 from StrangelyTyped/plain-array-binding
feat(core): Allow binding a column to the row entity itself
2 parents f3bf313 + 65e49fd commit 739e578

File tree

6 files changed

+163
-3
lines changed

6 files changed

+163
-3
lines changed

misc/tutorial/323_more_binding.ngdoc

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
@ngdoc overview
2+
@name Tutorial: 323 More Binding examples
3+
@description
4+
5+
UI-Grid can also bind be to a one-dimensional array of primitives - in this case using `uiGridConstants.ENTITY_BINDING` will use the entire entry in the data array as the value for the cell instead of a field therein. This is useful if the data is an array of strings, or also if a cell filter needs access to multiple fields within each row object.
6+
7+
@example
8+
<example module="app">
9+
<file name="app.js">
10+
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.edit']);
11+
12+
app.controller('OneDimensionCtrl', ['$scope', 'uiGridConstants', function ($scope, uiGridConstants) {
13+
14+
$scope.gridOptions = {
15+
enableSorting: true,
16+
columnDefs: [
17+
{ name:'Name', field: uiGridConstants.ENTITY_BINDING }
18+
],
19+
data : [
20+
"John Rogers",
21+
"David Michaels",
22+
"Andrew Johnson",
23+
"Donald McDonald"
24+
]
25+
};
26+
}]);
27+
28+
29+
app.filter('calculatePercentage', function () {
30+
return function (input, resultField, maxField) {
31+
return Math.floor((input[resultField] * 100) / input[maxField]) + "%";
32+
};
33+
});
34+
app.controller('ComplexFilterCtrl', ['$scope', 'uiGridConstants', function ($scope, uiGridConstants) {
35+
36+
$scope.gridOptions = {
37+
enableSorting: true,
38+
columnDefs: [
39+
{ name:'Exam', field: 'examName' },
40+
{ name:'Possible Score', field: 'maxScore' },
41+
{ name:'Your Score', field: 'actualScore' },
42+
{ name:'Percentage', field: uiGridConstants.ENTITY_BINDING, cellFilter: 'calculatePercentage:"actualScore":"maxScore"', sortCellFiltered: true, enableCellEdit: false }
43+
],
44+
data : [
45+
{
46+
examName: 'Basic Trig',
47+
maxScore: 105,
48+
actualScore: 77
49+
},
50+
{
51+
examName: 'Graph Theory',
52+
maxScore: 85,
53+
actualScore: 82
54+
},
55+
{
56+
examName: 'Counting',
57+
maxScore: 40,
58+
actualScore: 12
59+
},
60+
]
61+
};
62+
}]);
63+
</file>
64+
<file name="index.html">
65+
<div ng-controller="OneDimensionCtrl">
66+
<h3>Array of Strings Example</h3>
67+
<div id="grid1" ui-grid="gridOptions" ui-grid-edit class="grid"></div>
68+
</div>
69+
<div ng-controller="ComplexFilterCtrl">
70+
<h3>Complex CellFilter Example</h3>
71+
<div id="grid2" ui-grid="gridOptions" ui-grid-edit class="grid"></div>
72+
</div>
73+
</file>
74+
<file name="main.css">
75+
.grid {
76+
width: 500px;
77+
height: 250px;
78+
}
79+
</file>
80+
<file name="1d-scenario.js">
81+
var gridTestUtils = require('../../test/e2e/gridTestUtils.spec.js');
82+
it('grid should have four visible rows and one column', function () {
83+
gridTestUtils.expectRowCount( 'grid1', 4 );
84+
gridTestUtils.expectHeaderColumnCount( 'grid1', 1 );
85+
});
86+
87+
it('headers as specified', function () {
88+
gridTestUtils.expectHeaderCellValueMatch( 'grid1', 0, 'Name' );
89+
});
90+
91+
it('row values should be as expected', function () {
92+
gridTestUtils.expectRowValuesMatch( 'grid1', 0, [ 'John Rogers' ]);
93+
gridTestUtils.expectRowValuesMatch( 'grid1', 1, [ 'David Michaels' ]);
94+
gridTestUtils.expectRowValuesMatch( 'grid1', 2, [ 'Andrew Johnson' ]);
95+
gridTestUtils.expectRowValuesMatch( 'grid1', 3, [ 'Donald McDonald' ]);
96+
});
97+
</file>
98+
<file name="filter-scenario.js">
99+
var gridTestUtils = require('../../test/e2e/gridTestUtils.spec.js');
100+
it('grid should have four visible rows and 4 columns', function () {
101+
gridTestUtils.expectRowCount( 'grid2', 4 );
102+
gridTestUtils.expectHeaderColumnCount( 'grid2', 4 );
103+
});
104+
105+
it('headers as specified', function () {
106+
gridTestUtils.expectHeaderCellValueMatch( 'grid2', 0, 'Exam' );
107+
gridTestUtils.expectHeaderCellValueMatch( 'grid2', 1, 'Possible Exam' );
108+
gridTestUtils.expectHeaderCellValueMatch( 'grid2', 2, 'Actual Exam' );
109+
gridTestUtils.expectHeaderCellValueMatch( 'grid2', 3, 'Percentage' );
110+
});
111+
112+
it('row values should be as expected', function () {
113+
gridTestUtils.expectRowValuesMatch( 'grid2', 0, [ 'Basic Trig', '105', '77', '73%' ]);
114+
gridTestUtils.expectRowValuesMatch( 'grid2', 1, [ 'Graph Theory', '85', '82', '96%' ]);
115+
gridTestUtils.expectRowValuesMatch( 'grid2', 2, [ 'Counting', '40', '12', '30%' ]);
116+
});
117+
</file>
118+
</example>
119+
</example>

src/js/core/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
APOS_REGEXP: /'/g,
2525
BRACKET_REGEXP: /^(.*)((?:\s*\[\s*\d+\s*\]\s*)|(?:\s*\[\s*"(?:[^"\\]|\\.)*"\s*\]\s*)|(?:\s*\[\s*'(?:[^'\\]|\\.)*'\s*\]\s*))(.*)$/,
2626
COL_CLASS_PREFIX: 'ui-grid-col',
27+
ENTITY_BINDING: '$$this',
2728
events: {
2829
GRID_SCROLL: 'uiGridScroll',
2930
COLUMN_MENU_SHOWN: 'uiGridColMenuShown',

src/js/core/factories/Grid.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,11 @@ angular.module('ui.grid')
956956
* @param {GridColumn} col col object
957957
*/
958958
Grid.prototype.getQualifiedColField = function (col) {
959-
return 'row.entity.' + gridUtil.preEval(col.field);
959+
var base = 'row.entity';
960+
if ( col.field === uiGridConstants.ENTITY_BINDING ) {
961+
return base;
962+
}
963+
return gridUtil.preEval(base + '.' + col.field);
960964
};
961965

962966
/**

src/js/core/factories/GridRow.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(function(){
22

33
angular.module('ui.grid')
4-
.factory('GridRow', ['gridUtil', function(gridUtil) {
4+
.factory('GridRow', ['gridUtil', 'uiGridConstants', function(gridUtil, uiGridConstants) {
55

66
/**
77
* @ngdoc function
@@ -94,7 +94,11 @@ angular.module('ui.grid')
9494
* @returns {string} resulting name that can be evaluated against a row
9595
*/
9696
GridRow.prototype.getEntityQualifiedColField = function(col) {
97-
return gridUtil.preEval('entity.' + col.field);
97+
var base = 'entity';
98+
if ( col.field === uiGridConstants.ENTITY_BINDING ) {
99+
return base;
100+
}
101+
return gridUtil.preEval(base + '.' + col.field);
98102
};
99103

100104

test/unit/core/factories/Grid.spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,30 @@ describe('Grid factory', function () {
568568

569569
});
570570

571+
it('should bind correctly to $$this', function() {
572+
var colDefs = [
573+
{name: 'thisProp', field: '$$this'}
574+
];
575+
var grid = new Grid({ id: 1, columnDefs:colDefs });
576+
var data = [
577+
"abc",
578+
"def"
579+
];
580+
var rows = [
581+
new GridRow(data[0], 1, grid),
582+
new GridRow(data[1], 2, grid)
583+
];
584+
585+
grid.buildColumns();
586+
grid.modifyRows(data);
587+
588+
expect(grid.getCellValue(rows[0], grid.getColumn('thisProp'))).toBe('abc');
589+
expect(grid.getCellValue(rows[1], grid.getColumn('thisProp'))).toBe('def');
590+
591+
expect(grid.getCellDisplayValue(rows[0], grid.getColumn('thisProp'))).toBe('abc');
592+
expect(grid.getCellDisplayValue(rows[1], grid.getColumn('thisProp'))).toBe('def');
593+
});
594+
571595
it('should apply angularjs filters', function(){
572596
var colDefs = [
573597
{displayName:'date', field:'dateProp', cellFilter: 'date:"yyyy-MM-dd"'},

test/unit/core/factories/GridRow.spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ describe('GridRow factory', function () {
3939
expect(gridRow.getQualifiedColField(col)).toBe('row.entity[\'simpleProp\']');
4040
});
4141

42+
it('binds correctly to $$this', function() {
43+
var gridRow = new GridRow(entity,0,grid);
44+
var col = {
45+
field: '$$this'
46+
};
47+
expect(gridRow.getQualifiedColField(col)).toBe('row.entity');
48+
});
49+
4250
});
4351

4452

0 commit comments

Comments
 (0)