UNPKG

6.23 kBJavaScriptView Raw
1import {Feature} from '../feature';
2import {createElm, createText, elm, removeElm} from '../dom';
3import {EMPTY_FN, isNull} from '../types';
4import {defaultsStr, defaultsFn} from '../settings';
5import {LEFT} from './toolbar';
6
7/**
8 * Rows counter UI component
9 * @export
10 * @class RowsCounter
11 * @extends {Feature}
12 */
13export class RowsCounter extends Feature {
14
15 /**
16 * Creates an instance of RowsCounter
17 * @param {TableFilter} tf TableFilter instance
18 */
19 constructor(tf) {
20 super(tf, RowsCounter);
21
22 // TableFilter configuration
23 let f = this.config.rows_counter || {};
24
25 /**
26 * ID of custom container element
27 * @type {String}
28 */
29 this.targetId = defaultsStr(f.target_id, null);
30
31 /**
32 * Container DOM element
33 * @type {DOMElement}
34 * @private
35 */
36 this.container = null;
37
38 /**
39 * Container DOM element for label displaying the total number of rows
40 * @type {DOMElement}
41 * @private
42 */
43 this.label = null;
44
45 /**
46 * Text preceding the total number of rows
47 * @type {String}
48 */
49 this.text = defaultsStr(f.text, 'Rows: ');
50
51 /**
52 * Separator symbol appearing between the first and last visible rows of
53 * current page when paging is enabled. ie: Rows: 31-40 / 70
54 * @type {String}
55 */
56 this.fromToTextSeparator = defaultsStr(f.separator, '-');
57
58 /**
59 * Separator symbol appearing between the first and last visible rows of
60 * current page and the total number of filterable rows when paging is
61 * enabled. ie: Rows: 31-40 / 70
62 * @type {String}
63 */
64 this.overText = defaultsStr(f.over_text, ' / ');
65
66 /**
67 * Css class for container element
68 * @type {String}
69 */
70 this.cssClass = defaultsStr(f.css_class, 'tot');
71
72 /**
73 * Default position in toolbar ('left'|'center'|'right')
74 * @type {String}
75 */
76 this.toolbarPosition = defaultsStr(f.toolbar_position, LEFT);
77
78 /**
79 * Callback fired before the counter is refreshed
80 * @type {Function}
81 */
82 this.onBeforeRefreshCounter = defaultsFn(f.on_before_refresh_counter,
83 EMPTY_FN);
84
85 /**
86 * Callback fired after the counter is refreshed
87 * @type {Function}
88 */
89 this.onAfterRefreshCounter = defaultsFn(f.on_after_refresh_counter,
90 EMPTY_FN);
91 }
92
93 /**
94 * Initializes RowsCounter instance
95 */
96 init() {
97 if (this.initialized) {
98 return;
99 }
100
101 this.emitter.emit('initializing-feature', this, !isNull(this.targetId));
102
103 let tf = this.tf;
104
105 //rows counter container
106 let countDiv = createElm('div');
107 countDiv.className = this.cssClass;
108 //rows counter label
109 let countSpan = createElm('span');
110 let countText = createElm('span');
111 countText.appendChild(createText(this.text));
112
113 // counter is added to defined element
114 let targetEl = !this.targetId ?
115 tf.feature('toolbar').container(this.toolbarPosition) :
116 elm(this.targetId);
117
118 //default container: 'lDiv'
119 if (!this.targetId) {
120 countDiv.appendChild(countText);
121 countDiv.appendChild(countSpan);
122 targetEl.appendChild(countDiv);
123 } else {
124 //custom container, no need to append statusDiv
125 targetEl.appendChild(countText);
126 targetEl.appendChild(countSpan);
127 }
128 this.container = countDiv;
129 this.label = countSpan;
130
131 // subscribe to events
132 this.emitter.on(['after-filtering', 'grouped-by-page'],
133 () => this.refresh(tf.getValidRowsNb()));
134 this.emitter.on(['rows-changed'], () => this.refresh());
135
136 /** @inherited */
137 this.initialized = true;
138 this.refresh();
139
140 this.emitter.emit('feature-initialized', this);
141 }
142
143 /**
144 * Refreshes the rows counter
145 * @param {Number} p Optional parameter the total number of rows to display
146 */
147 refresh(p) {
148 if (!this.initialized || !this.isEnabled()) {
149 return;
150 }
151
152 let tf = this.tf;
153
154 this.onBeforeRefreshCounter(tf, this.label);
155
156 let totTxt;
157 if (!tf.paging) {
158 if (p && p !== '') {
159 totTxt = p;
160 } else {
161 totTxt = tf.getFilterableRowsNb() - tf.nbHiddenRows;
162 }
163 } else {
164 let paging = tf.feature('paging');
165 if (paging) {
166 let nbValidRows = tf.getValidRowsNb();
167 //paging start row
168 let pagingStartRow = parseInt(paging.startPagingRow, 10) +
169 ((nbValidRows > 0) ? 1 : 0);
170 let pagingEndRow =
171 (pagingStartRow + paging.pageLength) - 1 <=
172 nbValidRows ?
173 pagingStartRow + paging.pageLength - 1 :
174 nbValidRows;
175 totTxt = pagingStartRow + this.fromToTextSeparator +
176 pagingEndRow + this.overText + nbValidRows;
177 }
178 }
179
180 this.label.innerHTML = totTxt;
181 this.onAfterRefreshCounter(tf, this.label, totTxt);
182 }
183
184 /**
185 * Remove feature
186 */
187 destroy() {
188 if (!this.initialized) {
189 return;
190 }
191
192 if (!this.targetId && this.container) {
193 removeElm(this.container);
194 } else {
195 elm(this.targetId).innerHTML = '';
196 }
197 this.label = null;
198 this.container = null;
199
200 // unsubscribe to events
201 this.emitter.off(['after-filtering', 'grouped-by-page'],
202 () => this.refresh(tf.getValidRowsNb()));
203 this.emitter.off(['rows-changed'], () => this.refresh());
204
205 this.initialized = false;
206 }
207}