1 | /** |
||
2 | * @summary HideEmptyColumns |
||
3 | * @description Hide any (or specified) columns if no cells in the column(s) |
||
4 | * are populated with any values |
||
5 | * @version 1.2.1 |
||
6 | * @file dataTables.hideEmptyColumns.js |
||
7 | * @author Justin Hyland (http://www.justinhyland.com) |
||
8 | * @contact [email protected] |
||
9 | * @copyright Copyright 2015 Justin Hyland |
||
10 | * @url https://github.com/jhyland87/DataTables-Hide-Empty-Columns |
||
11 | * |
||
12 | * License MIT - http://datatables.net/license/mit |
||
13 | * |
||
14 | * Set the column visibility to hidden for any targeted columns that contain nothing |
||
15 | * but null or empty values. |
||
16 | * |
||
17 | * |
||
18 | * Parameters: |
||
19 | * |
||
20 | * ------------- |
||
21 | * hideEmptyCols |
||
22 | * Required: true |
||
23 | * Type: boolean|array|object |
||
24 | * Aliases: hideEmptyColumns |
||
25 | * Description: Primary setting, either target all columns, or specify an array for a list of cols, or an |
||
26 | * object for advanced settings |
||
27 | * Examples: hideEmptyCols: true |
||
28 | * hideEmptyCols: [ 0, 2, 'age' ] |
||
29 | * hideEmptyCols: { columns: [ 0, 2, 'age' ] } |
||
30 | * hideEmptyCols: { columns: true } |
||
31 | * |
||
32 | * hideEmptyCols.columns |
||
33 | * Required: false |
||
34 | * Type: boolean|array |
||
35 | * Description: Either true for all columns, or an array of indexes or dataSources |
||
36 | * Examples: [ 0, 2, 'age' ] // Column indexes 0 and 2, and the column name 'age' |
||
37 | * true // All columns |
||
38 | * |
||
39 | * hideEmptyCols.whiteList |
||
40 | * Required: false |
||
41 | * Type: boolean |
||
42 | * Default: true |
||
43 | * Description: Specify if the column list is to be targeted, or excluded |
||
44 | * |
||
45 | * hideEmptyCols.trim |
||
46 | * Required: false |
||
47 | * Type: boolean |
||
48 | * Default: true |
||
49 | * Description: Determines if column data values should be trimmed before checked for empty values |
||
50 | * |
||
51 | * hideEmptyCols.emptyVals |
||
52 | * Required: false |
||
53 | * Type: string|number|array|regex |
||
54 | * Description: Define one or more values that will be interpreted as "empty" |
||
55 | * Examples: [ '<br>', '</br>', '<BR>', '</BR>', ' ' ] // HTML Line breaks, and the HTML NBSP char |
||
56 | * /\<\/?br\>/i // Any possible HTML line break character that matches this pattern |
||
57 | * ['false', '0', /\<\/?br\>/i] // The string values 'false' and '0', and all HTML breaks |
||
58 | * |
||
59 | * hideEmptyCols.onStateLoad |
||
60 | * Required: false |
||
61 | * Type: boolean |
||
62 | * Default: true |
||
63 | * Description: Determines if the main _checkColumns function should execute after the DT state is loaded |
||
64 | * (when the DT stateSave option is enabled). This function will override the column visibility |
||
65 | * state in stateSave |
||
66 | * |
||
67 | * hideEmptyCols.perPage |
||
68 | * Required: false |
||
69 | * Type: boolean |
||
70 | * Description: Determine if columns should only be hidden if it has no values on the current page |
||
71 | * |
||
72 | * |
||
73 | * @example |
||
74 | * // Target all columns - Hide any columns that contain all null/empty values |
||
75 | * $('#example').DataTable({ |
||
76 | * hideEmptyCols: true |
||
77 | * }) |
||
78 | * |
||
79 | * @example |
||
80 | * // Target the column indexes 0 & 2 |
||
81 | * $('#example').DataTable({ |
||
82 | * hideEmptyCols: [0,2] |
||
83 | * }) |
||
84 | * |
||
85 | * @example |
||
86 | * // Target the column with 'age' data source |
||
87 | * $('#example').DataTable({ |
||
88 | * ajax: 'something.js', |
||
89 | * hideEmptyCols: ['age'], |
||
90 | * buttons: [ 'columnsToggle' ], |
||
91 | * columns: [ |
||
92 | * { name: 'name', data: 'name' }, |
||
93 | * { name: 'position', data: 'position' }, |
||
94 | * { name: 'age', data: 'age' } |
||
95 | * ] |
||
96 | * }) |
||
97 | * |
||
98 | * @example |
||
99 | * // Target everything *except* the columns 1, 2 & 3 |
||
100 | * $('#example').DataTable({ |
||
101 | * hideEmptyCols: { |
||
102 | * columns: [ 1, 2, 3 ], |
||
103 | * whiteList: false |
||
104 | * } |
||
105 | * }) |
||
106 | * |
||
107 | * @example |
||
108 | * // Target column indexes 1 and 4, adding custom empty values, and only hide the column if empty on current page |
||
109 | * $('#example').DataTable({ |
||
110 | * hideEmptyCols: { |
||
111 | * columns: [ 1, 4 ], |
||
112 | * perPage: true, |
||
113 | * emptyVals: [ '0', /(no|false|disabled)/i ] |
||
114 | * } |
||
115 | * }) |
||
116 | */ |
||
117 | //"use strict"; |
||
118 | (function(window, document, $) { |
||
119 | // On DT Initialization |
||
120 | $(document).on('init.dt', function(e, dtSettings) { |
||
121 | if (e.namespace !== 'dt') |
||
122 | return |
||
123 | |||
124 | // Check for either hideEmptyCols or hideEmptyColumns |
||
125 | var options = dtSettings.oInit.hideEmptyCols || dtSettings.oInit.hideEmptyColumns |
||
126 | |||
127 | // If neither of the above settings are found, then call it quits |
||
128 | if (!options) |
||
129 | return |
||
130 | |||
131 | // Helper function to get the value of a config item |
||
132 | var _cfgItem = function(item, def) { |
||
133 | if ($.isPlainObject(options) && typeof options[item] !== 'undefined') |
||
134 | return options[item] |
||
135 | |||
136 | return def |
||
137 | } |
||
138 | |||
139 | // Gather all the setting values which will be used |
||
140 | var api = new $.fn.dataTable.Api(dtSettings), |
||
141 | emptyCount = 0, |
||
142 | colList = [], |
||
143 | isWhiteList = !_cfgItem('whiteList', false), |
||
144 | perPage = _cfgItem('perPage'), |
||
145 | trimData = _cfgItem('trim', true), |
||
146 | onStateLoad = _cfgItem('onStateLoad', true) |
||
147 | |||
148 | // Helper function to determine if a cell is empty (including processing custom empty values) |
||
149 | var _isEmpty = function(colData) { |
||
150 | // Trim the data (unless its set to false) |
||
151 | if (trimData) |
||
152 | colData = $.trim(colData) |
||
153 | |||
154 | // Basic check |
||
155 | if (colData === null || colData.length === 0) |
||
156 | return true |
||
157 | |||
158 | // Default to false, any empty matches will reset to true |
||
159 | var retVal = false |
||
160 | |||
161 | var emptyVals = _cfgItem('emptyVals') |
||
162 | |||
163 | // Internal helper function to check the value against a custom defined empty value (which can be a |
||
164 | // regex pattern or a simple string) |
||
165 | var _checkEmpty = function(val, emptyVal) { |
||
166 | var objType = Object.prototype.toString.call(emptyVal) |
||
167 | |||
168 | var match = objType.match(/^\[object\s(.*)\]$/) |
||
169 | |||
170 | // If its a regex pattern, then handle it differently |
||
171 | if (match[1] === 'RegExp') |
||
172 | return val.match(emptyVal) |
||
173 | |||
174 | // Note: Should this comparison maybe use a lenient/loose comparison operator? hmm.. |
||
175 | return val === emptyVal |
||
176 | } |
||
177 | |||
178 | // If multiple custom empty values are defined in an array, then check each |
||
179 | if ($.isArray(emptyVals)) { |
||
180 | $.each(emptyVals, function(i, ev) { |
||
181 | if (_checkEmpty(colData, ev)) |
||
182 | retVal = true |
||
183 | }) |
||
184 | } |
||
185 | |||
186 | // Otherwise, just check the one, if set |
||
187 | else if (typeof emptyVals !== 'undefined') { |
||
188 | if (_checkEmpty(colData, emptyVals)) |
||
189 | retVal = true |
||
190 | } |
||
191 | |||
192 | return retVal |
||
193 | } |
||
194 | |||
195 | // If the hideEmptyCols setting is an Array (of column indexes to target) |
||
196 | if ($.isArray(options)) { |
||
197 | // And its populated.. |
||
198 | if (options.length !== 0) { |
||
199 | $.each(options, function(k, i) { |
||
200 | // Try to get the real column index from whatever was configured |
||
201 | var indx = api.column(i).index() |
||
202 | |||
203 | colList.push(typeof indx !== 'undefined' ? indx : i) |
||
204 | }) |
||
205 | } else { |
||
206 | // Otherwise, quit! since its just an empty array |
||
207 | return |
||
208 | } |
||
209 | } |
||
210 | |||
211 | // If hideEmptyCols setting is an Object (of plugin settings) |
||
212 | else if ($.isPlainObject(options)) { |
||
213 | // If options.columns isnt specifically |
||
214 | if (typeof options.columns === 'undefined' || options.columns === true) { |
||
215 | // Set colList to true, enabling every column as a target |
||
216 | colList = api.columns().indexes().toArray() |
||
217 | } |
||
218 | |||
219 | // If its an array, then it should contain the column indexs, so use that |
||
220 | else if ($.isArray(options.columns)) { |
||
221 | // Otherwise, set the colList |
||
222 | colList = options.columns |
||
223 | } |
||
224 | |||
225 | // If `options.columns` isn't an array (of indexes) or a boolean (disable/enable all columns), |
||
226 | // then throw a hissy fit |
||
227 | else if (typeof options.columns !== 'boolean') { |
||
228 | console.error('[Hide Empty Columns]: Expected typeof `columns` setting value to be an array, boolean or undefined, but received value type "%s"', typeof options.columns) |
||
229 | return |
||
230 | } |
||
231 | |||
232 | // The only thing left could be if its false, so just stop all together |
||
233 | else { |
||
234 | return |
||
235 | } |
||
236 | } |
||
237 | |||
238 | // If its just a basic 'true' targeting all columns.. |
||
239 | else if (options === true) { |
||
240 | // .. Then get the list of all column indexes |
||
241 | colList = api.columns().indexes().toArray() |
||
242 | } |
||
243 | |||
244 | // Anything else should just go away |
||
245 | else { |
||
246 | return |
||
247 | } |
||
248 | |||
249 | // Function to check the column rows |
||
250 | var _checkColumns = function() { |
||
251 | var info = api.page.info(), |
||
252 | colFilter = (perPage ? { |
||
253 | search: 'applied' |
||
254 | } : undefined) |
||
255 | |||
256 | // Iterate through the table, column by column |
||
257 | //api.columns({ search: 'applied' }).every(function () { |
||
258 | api.columns(colFilter).every(function() { |
||
259 | emptyCount = 0 |
||
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||
260 | |||
261 | // If the current column is *not* found in the list.. |
||
262 | if ($.inArray(this.index(), colList) === -1 // Check column index # |
||
263 | && |
||
264 | $.inArray(api.column(this.index()).dataSrc(), colList) === -1) // Check column name (dataSrc) |
||
265 | { |
||
266 | // .. And the list type is whitelist, then skip this loop |
||
267 | if (isWhiteList === true) return |
||
268 | } |
||
269 | // If the current column *is* found in the list.. |
||
270 | else { |
||
271 | // .. And the list type is blacklist, then skip this loop |
||
272 | if (isWhiteList === false) return |
||
273 | } |
||
274 | |||
275 | // This gets ALL data in current column.. Need just the visible rows |
||
276 | var data = this.data().toArray(), |
||
277 | isVis = false, |
||
278 | intStart = (perPage === true && info.serverSide === false ? info.start : 0), |
||
279 | intStop = (perPage === true && info.serverSide === false ? info.end : data.length), |
||
280 | dtState = api.state.loaded() |
||
0 ignored issues
–
show
|
|||
281 | |||
282 | //for( var i = 0; i < data.length; i ++ ) { |
||
283 | for (var i = intStart; i < intStop; i++) { |
||
284 | if (!_isEmpty(data[i])) { |
||
285 | isVis = true |
||
286 | break |
||
287 | } |
||
288 | } |
||
289 | |||
290 | // If the # of empty is the same as the length, then no values in col were found |
||
291 | api.column(this.index()).visible(isVis) |
||
292 | |||
293 | }) |
||
294 | } |
||
295 | |||
296 | // If stateSave is enabled in this DT instance, then toggle the column visibility afterwords |
||
297 | if (onStateLoad === true) |
||
298 | api.on('stateLoadParams.dt', _checkColumns) |
||
299 | |||
300 | // If were checking for each page, then attach functions to any events that may introduce or remove new |
||
301 | // columns/rows from the table (page, order, search and length) |
||
302 | if (perPage === true) |
||
303 | api |
||
304 | .on('page.dt', _checkColumns) |
||
305 | .on('search.dt', _checkColumns) |
||
306 | .on('order.dt', _checkColumns) |
||
307 | .on('length.dt', _checkColumns) |
||
308 | .on('draw.dt', _checkColumns) // triggers after data loaded with AJAX |
||
309 | |||
310 | // Run check for the initial page load |
||
311 | _checkColumns() |
||
312 | }) |
||
313 | })(window, document, jQuery) |