UNPKG

9.27 kBJavaScriptView Raw
1import {Feature} from '../feature';
2import {root} from '../root';
3import {createElm, createText, elm, removeElm} from '../dom';
4import {EMPTY_FN, isNull} from '../types';
5import {defaultsStr, defaultsFn} from '../settings';
6import {LEFT} from './toolbar';
7
8const EVENTS = [
9 'after-filtering',
10 'after-populating-filter',
11 'after-page-change',
12 'after-clearing-filters',
13 'after-page-length-change',
14 'after-reset-page',
15 'after-reset-page-length',
16 'after-loading-extensions',
17 'after-loading-themes'
18];
19
20/**
21 * Status bar UI component
22 * @export
23 * @class StatusBar
24 * @extends {Feature}
25 */
26export class StatusBar extends Feature {
27
28 /**
29 * Creates an instance of StatusBar
30 * @param {TableFilter} tf TableFilter instance
31 */
32 constructor(tf) {
33 super(tf, StatusBar);
34
35 // Configuration object
36 let f = this.config.status_bar || {};
37
38 /**
39 * ID of custom container element
40 * @type {String}
41 */
42 this.targetId = defaultsStr(f.target_id, null);
43
44 /**
45 * Container DOM element
46 * @type {DOMElement}
47 * @private
48 */
49 this.container = null;
50
51 /**
52 * Message container DOM element
53 * @type {DOMElement}
54 * @private
55 */
56 this.msgContainer = null;
57
58 /**
59 * Label container DOM element
60 * @type {DOMElement}
61 * @private
62 */
63 this.labelContainer = null;
64
65 /**
66 * Text preceding status message
67 * @type {String}
68 */
69 this.text = defaultsStr(f.text, '');
70
71 /**
72 * Css class for container element
73 * @type {String}
74 */
75 this.cssClass = defaultsStr(f.css_class, 'status');
76
77 /**
78 * Message visibility duration in milliseconds
79 * @type {Number}
80 * @private
81 */
82 this.delay = 250;
83
84 /**
85 * Callback fired before the message is displayed
86 * @type {Function}
87 */
88 this.onBeforeShowMsg = defaultsFn(f.on_before_show_msg, EMPTY_FN);
89
90 /**
91 * Callback fired after the message is displayed
92 * @type {Function}
93 */
94 this.onAfterShowMsg = defaultsFn(f.on_after_show_msg, EMPTY_FN);
95
96 /**
97 * Message appearing upon filtering
98 * @type {String}
99 */
100 this.msgFilter = defaultsStr(f.msg_filter, 'Filtering data...');
101
102 /**
103 * Message appearing when a drop-down filter is populated
104 * @type {String}
105 */
106 this.msgPopulate = defaultsStr(f.msg_populate, 'Populating filter...');
107
108 /**
109 * Message appearing when a checklist filter is populated
110 * @type {String}
111 */
112 this.msgPopulateCheckList = defaultsStr(f.msg_populate_checklist,
113 'Populating list...');
114
115 /**
116 * Message appearing when a pagination page is changed
117 * @type {String}
118 */
119 this.msgChangePage = defaultsStr(f.msg_change_page,
120 'Collecting paging data...');
121
122 /**
123 * Message appearing when filters are cleared
124 * @type {String}
125 */
126 this.msgClear = defaultsStr(f.msg_clear, 'Clearing filters...');
127
128 /**
129 * Message appearing when the page length is changed
130 * @type {String}
131 */
132 this.msgChangeResults = defaultsStr(f.msg_change_results,
133 'Changing results per page...');
134
135 /**
136 * Message appearing when the page is re-set
137 * @type {String}
138 */
139 this.msgResetPage = defaultsStr(f.msg_reset_page, 'Re-setting page...');
140
141 /**
142 * Message appearing when the page length is re-set
143 * @type {String}
144 */
145 this.msgResetPageLength = defaultsStr(f.msg_reset_page_length,
146 'Re-setting page length...');
147
148 /**
149 * Message appearing upon column sorting
150 * @type {String}
151 */
152 this.msgSort = defaultsStr(f.msg_sort, 'Sorting data...');
153
154 /**
155 * Message appearing when extensions are loading
156 * @type {String}
157 */
158 this.msgLoadExtensions = defaultsStr(f.msg_load_extensions,
159 'Loading extensions...');
160
161 /**
162 * Message appearing when themes are loading
163 * @type {String}
164 */
165 this.msgLoadThemes = defaultsStr(f.msg_load_themes,
166 'Loading theme(s)...');
167
168 /**
169 * Default position in toolbar ('left'|'center'|'right')
170 * @type {String}
171 */
172 this.toolbarPosition = defaultsStr(f.toolbar_position, LEFT);
173 }
174
175 /**
176 * Initializes StatusBar instance
177 */
178 init() {
179 if (this.initialized) {
180 return;
181 }
182
183 let tf = this.tf;
184 let emitter = this.emitter;
185
186 emitter.emit('initializing-feature', this, !isNull(this.targetId));
187
188 // status bar container
189 let statusDiv = createElm('div');
190 statusDiv.className = this.cssClass;
191
192 // status bar label
193 let statusSpan = createElm('span');
194 // preceding text
195 let statusSpanText = createElm('span');
196 statusSpanText.appendChild(createText(this.text));
197
198 // target element container
199 let targetEl = (!this.targetId) ?
200 tf.feature('toolbar').container(this.toolbarPosition) :
201 elm(this.targetId);
202
203 // default container
204 if (!this.targetId) {
205 statusDiv.appendChild(statusSpanText);
206 statusDiv.appendChild(statusSpan);
207 targetEl.appendChild(statusDiv);
208 } else {
209 // custom container, no need to append statusDiv
210 targetEl.appendChild(statusSpanText);
211 targetEl.appendChild(statusSpan);
212 }
213
214 this.container = statusDiv;
215 this.msgContainer = statusSpan;
216 this.labelContainer = statusSpanText;
217
218 // subscribe to events
219 emitter.on(['before-filtering'], () => this.message(this.msgFilter));
220 emitter.on(['before-populating-filter'],
221 () => this.message(this.msgPopulate));
222 emitter.on(['before-page-change'],
223 () => this.message(this.msgChangePage));
224 emitter.on(['before-clearing-filters'], () =>
225 this.message(this.msgClear));
226 emitter.on(['before-page-length-change'],
227 () => this.message(this.msgChangeResults));
228 emitter.on(['before-reset-page'],
229 () => this.message(this.msgResetPage));
230 emitter.on(['before-reset-page-length'],
231 () => this.message(this.msgResetPageLength));
232 emitter.on(['before-loading-extensions'],
233 () => this.message(this.msgLoadExtensions));
234 emitter.on(['before-loading-themes'],
235 () => this.message(this.msgLoadThemes));
236
237 emitter.on(EVENTS, () => this.message(''));
238
239 /** @inherited */
240 this.initialized = true;
241
242 emitter.emit('feature-initialized', this);
243 }
244
245 /**
246 * Display status message
247 * @param {String} [t=''] Message to be displayed
248 */
249 message(t = '') {
250 if (!this.isEnabled()) {
251 return;
252 }
253
254 this.onBeforeShowMsg(this.tf, t);
255
256 let d = t === '' ? this.delay : 1;
257 root.setTimeout(() => {
258 if (!this.initialized) {
259 return;
260 }
261 this.msgContainer.innerHTML = t;
262
263 this.onAfterShowMsg(this.tf, t);
264 }, d);
265 }
266
267 /**
268 * Destroy StatusBar instance
269 */
270 destroy() {
271 if (!this.initialized) {
272 return;
273 }
274
275 let emitter = this.emitter;
276
277 this.container.innerHTML = '';
278 if (!this.targetId) {
279 removeElm(this.container);
280 }
281 this.labelContainer = null;
282 this.msgContainer = null;
283 this.container = null;
284
285 // Unsubscribe to events
286 emitter.off(['before-filtering'], () => this.message(this.msgFilter));
287 emitter.off(['before-populating-filter'],
288 () => this.message(this.msgPopulate));
289 emitter.off(['before-page-change'],
290 () => this.message(this.msgChangePage));
291 emitter.off(['before-clearing-filters'],
292 () => this.message(this.msgClear));
293 emitter.off(['before-page-length-change'],
294 () => this.message(this.msgChangeResults));
295 emitter.off(['before-reset-page'], () =>
296 this.message(this.msgResetPage));
297 emitter.off(['before-reset-page-length'],
298 () => this.message(this.msgResetPageLength));
299 emitter.off(['before-loading-extensions'],
300 () => this.message(this.msgLoadExtensions));
301 emitter.off(['before-loading-themes'],
302 () => this.message(this.msgLoadThemes));
303
304 emitter.off(EVENTS, () => this.message(''));
305
306 this.initialized = false;
307 }
308}