Skip to content

Commit 65bbaab

Browse files
committed
feat(dynamic): support ng-if on td's
A TD element can receive a responsive-dynamic attribute/directive to be able to display the correct label. Fixes #16
1 parent 7ad5f68 commit 65bbaab

File tree

4 files changed

+98
-9
lines changed

4 files changed

+98
-9
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ 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;
3334
* Easy to apply any style on top of it;
3435
* Works with any base CSS framework;
3536
* Should integrate seamlessly with any table component you might choose to use.
@@ -77,6 +78,7 @@ All this work is based on the following assumptions:
7778
* table: wt-responsive-table
7879
* td: responsive-omit-title: title should be ommited
7980
* td: responsive-omit-if-empty: no row for empty cells
81+
* td: responsive-dynamic: add it when there's an `ng-if` directive applied to the element
8082

8183
## Installation
8284

@@ -97,6 +99,15 @@ All this work is based on the following assumptions:
9799

98100
## Special cases
99101

102+
### Column can be shown/hidden with ng-if
103+
104+
Also, more than one `td` exist for a single `th`...to deal with this add a `responsive-dynamic` attribute:
105+
106+
<tr>
107+
<td ng-if="condition" responsive-dynamic>tom</td>
108+
<td ng-if="!condition" responsive-dynamic>jerry</td>
109+
</tr>
110+
100111
### IE9 responsive hack
101112

102113
Because IE9 doesn't handle correctly a `display` CSS rule for `<td>`, if you need to support it, you can use the following style, only for IE9:

src/directive.js

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,73 @@
11
'use strict';
22

3+
function getHeaders(element) {
4+
return element.querySelectorAll('tr > th');
5+
}
6+
7+
function updateTitle(td, th) {
8+
var title = th && th.textContent;
9+
if (title && !td.getAttributeNode('data-title')) {
10+
td.setAttribute('data-title', title);
11+
}
12+
}
13+
14+
function colspan(td) {
15+
var colspan = td.getAttributeNode('colspan');
16+
return colspan ? parseInt(colspan.value) : 1;
17+
}
18+
319
function wtResponsiveTable() {
420
return {
521
restrict: 'A',
22+
controller: function ($element) {
23+
return {
24+
getHeader: function (td) {
25+
var headers = getHeaders($element[0]);
26+
if (headers.length) {
27+
var row = td.parentElement;
28+
var headerIndex = 0;
29+
var found = Array.prototype.some.call(row.querySelectorAll('td'), function (value, index) {
30+
if (value === td) {
31+
return true;
32+
}
33+
34+
headerIndex += colspan(value);
35+
});
36+
37+
return found ? headers.item(headerIndex) : null;
38+
}
39+
},
40+
}
41+
},
642
compile: function (element, attrs) {
743
attrs.$addClass('responsive');
8-
var headers = element[0].querySelectorAll('tr > th');
44+
var headers = getHeaders(element[0]);
945
if (headers.length) {
1046
var rows = element[0].querySelectorAll('tbody > tr');
1147
Array.prototype.forEach.call(rows, function(row) {
1248
var headerIndex = 0;
1349
Array.prototype.forEach.call(row.querySelectorAll('td'), function (value, index) {
14-
var th = value.parentElement.querySelector('th') || headers.item(headerIndex);
15-
var title = th && th.textContent;
16-
if (title && !value.getAttributeNode('data-title')) {
17-
value.setAttribute('data-title', title);
50+
if (!value.getAttributeNode('responsive-dynamic')) {
51+
var th = value.parentElement.querySelector('th') || headers.item(headerIndex);
52+
updateTitle(value, th);
1853
}
19-
20-
var colspan = value.getAttributeNode('colspan');
21-
headerIndex += colspan ? parseInt(colspan.value) : 1;
54+
55+
headerIndex += colspan(value);
2256
});
2357
});
2458
}
2559
}
2660
};
61+
}
62+
63+
function wtResponsiveDynamic() {
64+
return {
65+
restrict: 'A',
66+
require: '^^wtResponsiveTable',
67+
link: function (scope, element, attrs, tableCtrl) {
68+
var td = element[0];
69+
var th = tableCtrl.getHeader(td);
70+
updateTitle(td, th);
71+
}
72+
};
2773
}

src/module.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
'use strict';
22

33
angular.module('wt.responsive', [])
4-
.directive('wtResponsiveTable', [wtResponsiveTable]);
4+
.directive('wtResponsiveTable', [wtResponsiveTable])
5+
.directive('responsiveDynamic', [wtResponsiveDynamic]);

tests/directive.spec.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,4 +295,35 @@ describe('directive', function () {
295295

296296
expect(styles.paddingLeft).toBe('50%');
297297
});
298+
299+
describe('wt-responsive-column', function () {
300+
it('supports ng-if applied on TD', function () {
301+
var markup = [
302+
'<table wt-responsive-table>',
303+
' <thead>',
304+
' <tr>',
305+
' <th>column</th>',
306+
' </tr>',
307+
' </thead>',
308+
' <tbody>',
309+
' <tr>',
310+
' <td ng-if="!condition" responsive-dynamic>tom</td>',
311+
' <td ng-if="condition" responsive-dynamic>jerry</td>',
312+
' </tr>',
313+
' </tbody>',
314+
'</table>'
315+
].join('');
316+
var element = angular.element(markup);
317+
var scope = $rootScope.$new();
318+
scope.condition = true;
319+
320+
$compile(element)(scope);
321+
scope.$digest();
322+
323+
var els = element.find('tbody tr:first td');
324+
expect(els.eq(0).text()).toBe('jerry');
325+
expect(els.eq(0).attr('data-title')).toBe('column');
326+
});
327+
328+
});
298329
});

0 commit comments

Comments
 (0)