1/*!
2 * Column visibility buttons for Buttons and DataTables.
3 * © SpryMedia Ltd - datatables.net/license
4 */
5
6(function( factory ){
7	if ( typeof define === 'function' && define.amd ) {
8		// AMD
9		define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
10			return factory( $, window, document );
11		} );
12	}
13	else if ( typeof exports === 'object' ) {
14		// CommonJS
15		var jq = require('jquery');
16		var cjsRequires = function (root, $) {
17			if ( ! $.fn.dataTable ) {
18				require('datatables.net')(root, $);
19			}
20
21			if ( ! $.fn.dataTable.Buttons ) {
22				require('datatables.net-buttons')(root, $);
23			}
24		};
25
26		if (typeof window === 'undefined') {
27			module.exports = function (root, $) {
28				if ( ! root ) {
29					// CommonJS environments without a window global must pass a
30					// root. This will give an error otherwise
31					root = window;
32				}
33
34				if ( ! $ ) {
35					$ = jq( root );
36				}
37
38				cjsRequires( root, $ );
39				return factory( $, root, root.document );
40			};
41		}
42		else {
43			cjsRequires( window, jq );
44			module.exports = factory( jq, window, window.document );
45		}
46	}
47	else {
48		// Browser
49		factory( jQuery, window, document );
50	}
51}(function( $, window, document, undefined ) {
52'use strict';
53var DataTable = $.fn.dataTable;
54
55
56
57$.extend(DataTable.ext.buttons, {
58	// A collection of column visibility buttons
59	colvis: function (dt, conf) {
60		var node = null;
61		var buttonConf = {
62			extend: 'collection',
63			init: function (dt, n) {
64				node = n;
65			},
66			text: function (dt) {
67				return dt.i18n('buttons.colvis', 'Column visibility');
68			},
69			className: 'buttons-colvis',
70			closeButton: false,
71			buttons: [
72				{
73					extend: 'columnsToggle',
74					columns: conf.columns,
75					columnText: conf.columnText
76				}
77			]
78		};
79
80		// Rebuild the collection with the new column structure if columns are reordered
81		dt.on('column-reorder.dt' + conf.namespace, function (e, settings, details) {
82			dt.button(null, dt.button(null, node).node()).collectionRebuild([
83				{
84					extend: 'columnsToggle',
85					columns: conf.columns,
86					columnText: conf.columnText
87				}
88			]);
89		});
90
91		return buttonConf;
92	},
93
94	// Selected columns with individual buttons - toggle column visibility
95	columnsToggle: function (dt, conf) {
96		var columns = dt
97			.columns(conf.columns)
98			.indexes()
99			.map(function (idx) {
100				return {
101					extend: 'columnToggle',
102					columns: idx,
103					columnText: conf.columnText
104				};
105			})
106			.toArray();
107
108		return columns;
109	},
110
111	// Single button to toggle column visibility
112	columnToggle: function (dt, conf) {
113		return {
114			extend: 'columnVisibility',
115			columns: conf.columns,
116			columnText: conf.columnText
117		};
118	},
119
120	// Selected columns with individual buttons - set column visibility
121	columnsVisibility: function (dt, conf) {
122		var columns = dt
123			.columns(conf.columns)
124			.indexes()
125			.map(function (idx) {
126				return {
127					extend: 'columnVisibility',
128					columns: idx,
129					visibility: conf.visibility,
130					columnText: conf.columnText
131				};
132			})
133			.toArray();
134
135		return columns;
136	},
137
138	// Single button to set column visibility
139	columnVisibility: {
140		columns: undefined, // column selector
141		text: function (dt, button, conf) {
142			return conf._columnText(dt, conf);
143		},
144		className: 'buttons-columnVisibility',
145		action: function (e, dt, button, conf) {
146			var col = dt.columns(conf.columns);
147			var curr = col.visible();
148
149			col.visible(
150				conf.visibility !== undefined ? conf.visibility : !(curr.length ? curr[0] : false)
151			);
152		},
153		init: function (dt, button, conf) {
154			var that = this;
155			button.attr('data-cv-idx', conf.columns);
156
157			dt.on('column-visibility.dt' + conf.namespace, function (e, settings) {
158				if (!settings.bDestroying && settings.nTable == dt.settings()[0].nTable) {
159					that.active(dt.column(conf.columns).visible());
160				}
161			}).on('column-reorder.dt' + conf.namespace, function (e, settings, details) {
162				// Button has been removed from the DOM
163				if (conf.destroying) {
164					return;
165				}
166
167				if (dt.columns(conf.columns).count() !== 1) {
168					return;
169				}
170
171				// This button controls the same column index but the text for the column has
172				// changed
173				that.text(conf._columnText(dt, conf));
174
175				// Since its a different column, we need to check its visibility
176				that.active(dt.column(conf.columns).visible());
177			});
178
179			this.active(dt.column(conf.columns).visible());
180		},
181		destroy: function (dt, button, conf) {
182			dt.off('column-visibility.dt' + conf.namespace).off(
183				'column-reorder.dt' + conf.namespace
184			);
185		},
186
187		_columnText: function (dt, conf) {
188			// Use DataTables' internal data structure until this is presented
189			// is a public API. The other option is to use
190			// `$( column(col).node() ).text()` but the node might not have been
191			// populated when Buttons is constructed.
192			var idx = dt.column(conf.columns).index();
193			var title = dt.settings()[0].aoColumns[idx].sTitle;
194
195			if (!title) {
196				title = dt.column(idx).header().innerHTML;
197			}
198
199			title = title
200				.replace(/\n/g, ' ') // remove new lines
201				.replace(/<br\s*\/?>/gi, ' ') // replace line breaks with spaces
202				.replace(/<select(.*?)<\/select>/g, '') // remove select tags, including options text
203				.replace(/<!\-\-.*?\-\->/g, '') // strip HTML comments
204				.replace(/<.*?>/g, '') // strip HTML
205				.replace(/^\s+|\s+$/g, ''); // trim
206
207			return conf.columnText ? conf.columnText(dt, idx, title) : title;
208		}
209	},
210
211	colvisRestore: {
212		className: 'buttons-colvisRestore',
213
214		text: function (dt) {
215			return dt.i18n('buttons.colvisRestore', 'Restore visibility');
216		},
217
218		init: function (dt, button, conf) {
219			conf._visOriginal = dt
220				.columns()
221				.indexes()
222				.map(function (idx) {
223					return dt.column(idx).visible();
224				})
225				.toArray();
226		},
227
228		action: function (e, dt, button, conf) {
229			dt.columns().every(function (i) {
230				// Take into account that ColReorder might have disrupted our
231				// indexes
232				var idx =
233					dt.colReorder && dt.colReorder.transpose
234						? dt.colReorder.transpose(i, 'toOriginal')
235						: i;
236
237				this.visible(conf._visOriginal[idx]);
238			});
239		}
240	},
241
242	colvisGroup: {
243		className: 'buttons-colvisGroup',
244
245		action: function (e, dt, button, conf) {
246			dt.columns(conf.show).visible(true, false);
247			dt.columns(conf.hide).visible(false, false);
248
249			dt.columns.adjust();
250		},
251
252		show: [],
253
254		hide: []
255	}
256});
257
258
259return DataTable;
260}));
261