UNPKG

4.07 kBJavaScriptView Raw
1import {Feature} from '../feature';
2import {addClass, removeClass, hasClass} from '../dom';
3import {EMPTY_FN} from '../types';
4import {defaultsStr, defaultsFn} from '../settings';
5
6/**
7 * Visual indicator for filtered columns
8 * @export
9 * @class MarkActiveColumns
10 * @extends {Feature}
11 */
12export class MarkActiveColumns extends Feature {
13
14 /**
15 * Create an instance of MarkActiveColumns
16 * @param {TableFilter} tf TableFilter instance
17 */
18 constructor(tf) {
19 super(tf, 'markActiveColumns');
20
21 let config = this.config.mark_active_columns || {};
22
23 /**
24 * Css class for filtered (active) columns
25 * @type {String}
26 */
27 this.headerCssClass = defaultsStr(config.header_css_class,
28 'activeHeader');
29
30 /**
31 * Css class for filtered (active) column cells
32 * @type {String}
33 */
34 this.cellCssClass = defaultsStr(config.cell_css_class,
35 'activeCell');
36
37 /**
38 * Enable/disable column highlighting
39 * @type {Boolean}
40 */
41 this.highlightColumn = Boolean(config.highlight_column);
42
43 /**
44 * Callback fired before a column is marked as filtered
45 * @type {Function}
46 */
47 this.onBeforeActiveColumn = defaultsFn(config.on_before_active_column,
48 EMPTY_FN);
49
50 /**
51 * Callback fired after a column is marked as filtered
52 * @type {Function}
53 */
54 this.onAfterActiveColumn = defaultsFn(config.on_after_active_column,
55 EMPTY_FN);
56 }
57
58 /**
59 * Initialise MarkActiveColumns instance
60 */
61 init() {
62 if (this.initialized) {
63 return;
64 }
65
66 this.emitter.on(['before-filtering'], () => this.clearActiveColumns());
67 this.emitter.on(
68 ['cell-processed'],
69 (tf, colIndex) => this.markActiveColumn(colIndex)
70 );
71
72 /** @inherited */
73 this.initialized = true;
74 }
75
76 /**
77 * Clear filtered columns visual indicator (background color)
78 */
79 clearActiveColumns() {
80 let tf = this.tf;
81 tf.eachCol((idx) => {
82 removeClass(tf.getHeaderElement(idx), this.headerCssClass);
83
84 if (this.highlightColumn) {
85 this.eachColumnCell(idx,
86 (cell) => removeClass(cell, this.cellCssClass));
87 }
88 });
89 }
90
91 /**
92 * Mark currently filtered column
93 * @param {Number} colIndex Column index
94 */
95 markActiveColumn(colIndex) {
96 let tf = this.tf;
97 let header = tf.getHeaderElement(colIndex);
98 if (hasClass(header, this.headerCssClass)) {
99 return;
100 }
101
102 this.onBeforeActiveColumn(this, colIndex);
103
104 addClass(header, this.headerCssClass);
105
106 if (this.highlightColumn) {
107 this.eachColumnCell(colIndex,
108 (cell) => addClass(cell, this.cellCssClass));
109 }
110
111 this.onAfterActiveColumn(this, colIndex);
112 }
113
114 /**
115 * Column cells iterator
116 * TODO: make public and move into TableFilter if used elsewhere
117 * @param {Number} colIndex
118 * @param {Function} fn
119 * @param {DOMElement} tbl
120 * @private
121 */
122 eachColumnCell(colIndex, fn = EMPTY_FN, tbl = this.tf.dom()) {
123 // TODO: remove [].forEach when polyfill for PhanthomJs is available
124 [].forEach.call(
125 tbl.querySelectorAll(`tbody td:nth-child(${colIndex + 1})`), fn);
126 }
127
128 /**
129 * Remove feature
130 */
131 destroy() {
132 if (!this.initialized) {
133 return;
134 }
135
136 this.clearActiveColumns();
137 this.emitter.off(['before-filtering'], () => this.clearActiveColumns());
138 this.emitter.off(
139 ['cell-processed'],
140 (tf, colIndex) => this.markActiveColumn(colIndex)
141 );
142
143 /** @inherited */
144 this.initialized = false;
145 }
146}