Skip to content

Commit 2a3317c

Browse files
author
Andrew Perlitch
committed
expandable functionality
1 parent d454f2f commit 2a3317c

File tree

13 files changed

+199
-41
lines changed

13 files changed

+199
-41
lines changed

README.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The options object should be available on the parent scope of the `<ap-mesa>` el
6868

6969
| key | type | default | description |
7070
| ------------------ | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |
71-
| rowPadding | `number` | 10 | Number of rows to add before and after the viewport |
71+
| rowPadding | `number` | 10 | Number of pixels to pre-render before and after the viewport |
7272
| sortClasses | `Array` | (see below) | |
7373
| storage | `Object` | undefined | |
7474
| storageHash | `String` | undefined | Non-sequential "version" hash used to identify and compare items in `storage`. |
@@ -88,7 +88,8 @@ The options object should be available on the parent scope of the `<ap-mesa>` el
8888
| fillHeight | `boolean` | false | If true, the table will fill the calculated height of the parent element. Note that this overrides `bodyHeight`. The table will listen for `'apMesa:resize'` events from the rootScope to recalculate the height. |
8989
| fixedHeight | `boolean` | false | If true, the table body will always have a height of `bodyHeight`, regardless of whether the rows fill up the vertical space. |
9090
| onRegisterApi | `function` | {} | Provides a access to select table controller methods, including selectAll, deselectAll, isSelectedAll, setLoading, etc. |
91-
| getter | `function` | {} | Customize the way to get column value. If not specified, get columen value by row[column.key] |
91+
| getter | `function` | {} | Customize the way to get column value. If not specified, get columen value by row[column.key] |
92+
| expandableTemplateUrl | `String` | undefined | A template reference to be used for the expandable row feature. See *Expandable Rows* below. |
9293

9394

9495
### Loading
@@ -228,6 +229,30 @@ There is a special type of column called a selector, which will render as a chec
228229
]
229230

230231

232+
Expandable Rows
233+
---------------
234+
235+
To use the expandable rows feature, you will need to specify a expandableTemplateUrl call `toggleRowExpand()` from a custom column template. For example, a column definition may look like:
236+
237+
```javascript
238+
$scope.tableOptions = {
239+
expandableTemplateUrl: 'path/to/panel-template.html'
240+
};
241+
$scope.columns = [
242+
{
243+
id: 'foo',
244+
template: '<a href="" ng-click="toggleRowExpand()">CLICK TO EXPAND</a>'
245+
},
246+
...
247+
];
248+
```
249+
250+
There will also be a property on row scope called `rowIsExpanded` which is a boolean indicating if the row's panel is expanded.
251+
It's also recommended to make the `rowPadding` option at least as large as the expected pixel height of the expanded panels.
252+
253+
For a complete example, please check out `/app/scripts/controllers/expandable.js`.
254+
255+
231256

232257
Browser Support
233258
---------------

app/scripts/controllers/expandable.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@ angular.module('apMesa.ghPage')
44
.controller('ExpandableCtrl', function($scope, $q, phoneData, $templateCache) {
55

66
$scope.my_table_options = {
7-
expandableTemplateUrl: 'views/expandable-panel.html'
7+
expandableTemplateUrl: 'views/expandable-panel.html',
8+
bodyHeight: 600,
9+
rowPadding: 600
810
};
911
$scope.my_selected_rows = [];
1012
$scope.my_table_columns = [
1113
{
1214
id: 'name',
1315
key: 'DeviceName',
1416
label: 'Phone',
17+
sort: 'string',
18+
filter: 'like',
1519
template: '<a href="" ng-click="toggleRowExpand()">' +
1620
'<i class="glyphicon glyphicon-triangle-right" ng-if="!rowIsExpanded"></i>' +
1721
'<i class="glyphicon glyphicon-triangle-bottom" ng-if="rowIsExpanded"></i>' +
@@ -21,11 +25,13 @@ angular.module('apMesa.ghPage')
2125
{
2226
id: 'brand',
2327
key: 'Brand',
28+
sort: 'string',
2429
label: 'Brand'
2530
},
2631
{
2732
id: 'tech',
2833
key: 'technology',
34+
sort: 'string',
2935
label: 'Tech'
3036
}
3137
];

dist/ap-mesa.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,5 @@ when a discreet width has been set on it */
175175

176176
table tbody .ap-mesa-dummy-row td {
177177
border-top: none;
178+
padding: 0;
178179
}

dist/ap-mesa.js

Lines changed: 97 additions & 20 deletions
Large diffs are not rendered by default.

dist/ap-mesa.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/ap-mesa.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ap-mesa.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,5 @@ when a discreet width has been set on it */
144144
}
145145
table tbody .ap-mesa-dummy-row td {
146146
border-top: none;
147+
padding: 0;
147148
}

src/controllers/ApMesaController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ angular.module('apMesa.controllers.ApMesaController', [
411411
$scope.calculateRowLimit = function() {
412412
var rowHeight = $scope.scrollDiv.find('.ap-mesa-rendered-rows tr').height();
413413
$scope.rowHeight = rowHeight || $scope.options.defaultRowHeight || 20;
414-
$scope.rowLimit = Math.ceil($scope.options.bodyHeight / $scope.rowHeight) + $scope.options.rowPadding*2;
414+
$scope.rowLimit = Math.ceil(($scope.options.bodyHeight + $scope.options.rowPadding*2) / $scope.rowHeight);
415415
};
416416

417417
}]);

src/directives/apMesa.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ angular.module('apMesa.directives.apMesa', [
115115
scope.options = scope.options || {};
116116
defaults(scope.options, {
117117
bgSizeMultiplier: 1,
118-
rowPadding: 10,
118+
rowPadding: 300,
119119
bodyHeight: 300,
120120
fixedHeight: false,
121121
defaultRowHeight: 40,
@@ -205,15 +205,54 @@ angular.module('apMesa.directives.apMesa', [
205205

206206
scope.calculateRowLimit();
207207

208-
var scrollTop = scope.scrollDiv[0].scrollTop;
208+
var scrollTop = scope.scrollDiv[0].scrollTop - scope.options.rowPadding;
209209

210210
var rowHeight = scope.rowHeight;
211211

212212
if (rowHeight === 0) {
213213
return false;
214214
}
215215

216-
scope.rowOffset = Math.max(0, Math.floor(scrollTop / rowHeight) - scope.options.rowPadding);
216+
var rowOffset = 0;
217+
var runningTotalScroll = 0;
218+
var expandedOffsets = Object.keys(scope.expandedRows)
219+
.map(function(i) { return parseInt(i); })
220+
.sort();
221+
222+
// push the max offset so this works in constant time
223+
// when no expanded rows are present
224+
expandedOffsets.push(scope.filterState.filterCount);
225+
226+
// a counter that holds the last offset of an expanded row
227+
for (var i = 0; i <= expandedOffsets.length; i++) {
228+
// the offset of the expanded row
229+
var expandedOffset = expandedOffsets[i];
230+
231+
// the height of the collapsed rows before this expanded row
232+
// and after the previous expanded row
233+
var rowsHeight = (expandedOffset - rowOffset) * rowHeight;
234+
235+
// check if the previous rows is more than enough
236+
if (runningTotalScroll + rowsHeight >= scrollTop) {
237+
rowOffset += Math.floor((scrollTop - runningTotalScroll)/rowHeight);
238+
break;
239+
}
240+
// otherwise add it to the running total
241+
runningTotalScroll += rowsHeight;
242+
243+
// the pixels that this row's expanded panel displaces
244+
var expandedPixels = scope.expandedRows[expandedOffset];
245+
runningTotalScroll += expandedPixels;
246+
rowOffset = expandedOffset;
247+
248+
// Check if the expanded panel put us over the edge
249+
if (runningTotalScroll >= scrollTop) {
250+
rowOffset--;
251+
break;
252+
}
253+
}
254+
255+
scope.rowOffset = Math.max(0, rowOffset);
217256

218257
scrollDeferred.resolve();
219258

src/directives/apMesaDummyRows.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@ angular.module('apMesa.directives.apMesaDummyRows', [])
3232
link: function(scope, element, attrs) {
3333

3434
scope.$watch(attrs.apMesaDummyRows, function(offsetRange) {
35-
console.log(offsetRange);
3635
var rowsHeight = (offsetRange[1] - offsetRange[0]) * scope.rowHeight;
3736
for (var k in scope.expandedRows) {
3837
var kInt = parseInt(k);
39-
if (kInt >= offsetRange[0] && kInt <= offsetRange[1]) {
38+
if (kInt >= offsetRange[0] && kInt < offsetRange[1]) {
4039
rowsHeight += scope.expandedRows[k];
4140
}
4241
}

0 commit comments

Comments
 (0)