Skip to content

Commit 961fc42

Browse files
committed
fix(directive): support ng-repeat on th's
Closes #12
1 parent ee2b1bf commit 961fc42

File tree

3 files changed

+73
-21
lines changed

3 files changed

+73
-21
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ All this work is based on the following assumptions:
3030
* Angular native implementation compatible with 1.3.4+;
3131
* Keep things DRY;
3232
* Supports static and dynamic (ng-repeat) rows;
33-
* Support conditionally shown (ng-if) columns;
33+
* Supports conditionally shown (ng-if) columns;
34+
* Supports dynamic headers (ng-repeat);
3435
* Easy to apply any style on top of it;
3536
* Works with any base CSS framework;
3637
* Should integrate seamlessly with any table component you might choose to use.
@@ -107,8 +108,7 @@ It's possible to override a header with a `data-title` attribute:
107108
<tr>
108109
<td data-title="column 1">tom</td>
109110
<td data-title="column 2">jerry</td>
110-
</tr>
111-
111+
</tr>
112112

113113
### Column can be shown/hidden with ng-if
114114

@@ -117,7 +117,12 @@ Also, more than one `td` exist for a single `th`...to deal with this add a `resp
117117
<tr>
118118
<td ng-if="condition" responsive-dynamic>tom</td>
119119
<td ng-if="!condition" responsive-dynamic>jerry</td>
120-
</tr>
120+
</tr>
121+
122+
### Changes to header text doesn't reflect in responsive mode
123+
124+
This is by design. To avoid expensive digest cycles only the content from the first digest cycle is used.
125+
There are no watches being setup.
121126

122127
### IE9 responsive hack
123128

src/directive.js

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function updateTitle(td, th) {
1414
function colspan(td) {
1515
var colspan = td.getAttributeNode('colspan');
1616
return colspan ? parseInt(colspan.value) : 1;
17-
}
17+
}
1818

1919
function wtResponsiveTable() {
2020
return {
@@ -25,7 +25,7 @@ function wtResponsiveTable() {
2525
var headers = getHeaders($element[0]);
2626
if (headers.length) {
2727
var row = td.parentElement;
28-
var headerIndex = 0;
28+
var headerIndex = 0;
2929
var found = Array.prototype.some.call(row.querySelectorAll('td'), function (value, index) {
3030
if (value === td) {
3131
return true;
@@ -40,21 +40,33 @@ function wtResponsiveTable() {
4040
}
4141
},
4242
compile: function (element, attrs) {
43-
attrs.$addClass('responsive');
44-
var headers = getHeaders(element[0]);
45-
if (headers.length) {
46-
var rows = element[0].querySelectorAll('tbody > tr');
47-
Array.prototype.forEach.call(rows, function(row) {
48-
var headerIndex = 0;
49-
Array.prototype.forEach.call(row.querySelectorAll('td'), function (value, index) {
50-
if (!value.getAttributeNode('responsive-dynamic')) {
51-
var th = value.parentElement.querySelector('th') || headers.item(headerIndex);
52-
updateTitle(value, th);
53-
}
43+
function apply() {
44+
var headers = getHeaders(element[0]);
45+
if (headers.length) {
46+
var rows = element[0].querySelectorAll('tbody > tr');
47+
Array.prototype.forEach.call(rows, function(row) {
48+
var headerIndex = 0;
49+
Array.prototype.forEach.call(row.querySelectorAll('td'), function (value, index) {
50+
if (!value.getAttributeNode('responsive-dynamic')) {
51+
var th = value.parentElement.querySelector('th') || headers.item(headerIndex);
52+
updateTitle(value, th);
53+
}
5454

55-
headerIndex += colspan(value);
55+
headerIndex += colspan(value);
56+
});
5657
});
57-
});
58+
}
59+
}
60+
61+
attrs.$addClass('responsive');
62+
if (Array.prototype.some.call(element.find('th'), function (it) {
63+
return it.getAttributeNode('ng-repeat') || it.getAttributeNode('data-ng-repeat')
64+
})) {
65+
setTimeout(function () {
66+
apply();
67+
}, 0);
68+
} else {
69+
apply();
5870
}
5971
}
6072
};
@@ -66,8 +78,8 @@ function wtResponsiveDynamic() {
6678
require: '^^wtResponsiveTable',
6779
link: function (scope, element, attrs, tableCtrl) {
6880
var td = element[0];
69-
var th = tableCtrl.getHeader(td);
81+
var th = tableCtrl.getHeader(td);
7082
updateTitle(td, th);
7183
}
7284
};
73-
}
85+
}

tests/directive.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,41 @@ describe('directive', function () {
233233
expect(firstDataRow.eq(3).attr('data-title')).toBe('Forth title');
234234
});
235235

236+
it('supports ng-repeat applied on TH', function (done) {
237+
var markup = [
238+
'<table wt-responsive-table>',
239+
' <thead>',
240+
' <tr>',
241+
' <th ng-repeat="header in headers">{{header}}</th>',
242+
' </tr>',
243+
' </thead>',
244+
' <tbody>',
245+
' <tr>',
246+
' <td>Column 1 - Content</td>',
247+
' <td>Column 2 - Content</td>',
248+
' </tr>',
249+
' </tbody>',
250+
'</table>'
251+
].join('');
252+
var element = angular.element(markup);
253+
var scope = $rootScope.$new();
254+
scope.headers = ['Column 1', 'Column 2'];
255+
256+
$compile(element)(scope);
257+
scope.$digest();
258+
259+
var firstDataRow = element.find('tbody tr:first td');
260+
261+
setTimeout(() => {
262+
expect(firstDataRow.eq(0).attr('data-title')).toBe('Column 1');
263+
expect(firstDataRow.eq(0).text()).toBe('Column 1 - Content');
264+
expect(firstDataRow.eq(1).attr('data-title')).toBe('Column 2');
265+
expect(firstDataRow.eq(1).text()).toBe('Column 2 - Content');
266+
267+
done();
268+
}, 0);
269+
});
270+
236271
it('supports ng-if applied on TD with data-title', function () {
237272
var markup = [
238273
'<table wt-responsive-table>',

0 commit comments

Comments
 (0)